Merge branch 'android-msm-bonito-4.9-pi-qpr3' into android-msm-pixel-4.9
JUN 2019.3
Bug: 129973133
Change-Id: Ie2f190f356952d6b8143b1f4afcdd0e36fc2a355
Signed-off-by: Max Shi <meixuanshi@google.com>
diff --git a/Kbuild b/Kbuild
index 67d3ac1..b178e53 100644
--- a/Kbuild
+++ b/Kbuild
@@ -184,6 +184,15 @@
#Flag to enable DISA
CONFIG_WLAN_FEATURE_DISA := y
+ #Flag to enable OWE
+ CONFIG_WLAN_FEATURE_OWE := y
+
+ #Flag to enable GMAC
+ CONFIG_WLAN_FEATURE_GMAC := y
+
+ #Flag to enable SAE
+ CONFIG_WLAN_FEATURE_SAE := y
+
#Flag to enable Fast Path feature
CONFIG_WLAN_FASTPATH := y
@@ -1401,6 +1410,18 @@
CDEFINES += -DWLAN_POWER_DEBUGFS
endif
+ifeq ($(CONFIG_WLAN_FEATURE_OWE),y)
+CDEFINES += -DWLAN_FEATURE_OWE
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_GMAC),y)
+CDEFINES += -DWLAN_FEATURE_GMAC
+endif
+
+ifeq ($(CONFIG_WLAN_FEATURE_SAE),y)
+CDEFINES += -DWLAN_FEATURE_SAE
+endif
+
ifeq ($(BUILD_DIAG_VERSION),1)
CDEFINES += -DFEATURE_WLAN_DIAG_SUPPORT
CDEFINES += -DFEATURE_WLAN_DIAG_SUPPORT_CSR
@@ -1833,7 +1854,6 @@
CDEFINES += -DWLAN_FEATURE_APF
endif
-CONFIG_WLAN_FEATURE_SARV1_TO_SARV2 := y
ifeq ($(CONFIG_WLAN_FEATURE_SARV1_TO_SARV2), y)
CDEFINES += -DWLAN_FEATURE_SARV1_TO_SARV2
endif
diff --git a/Kconfig b/Kconfig
index fafceef..bed09cd 100644
--- a/Kconfig
+++ b/Kconfig
@@ -135,8 +135,4 @@
config CONFIG_BUILD_TIMESTAMP
bool "Embed timestamp in wlan version"
default n
-
-config WLAN_FEATURE_SARV1_TO_SARV2
- bool "Enable conversion of SAR v1 to v2 feature"
- default n
endif # QCA_CLD_WLAN
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..237a6cb
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,2 @@
+kumaranand@google.com
+arabawy@google.com
diff --git a/core/bmi/src/ol_fw.c b/core/bmi/src/ol_fw.c
index 7d181b2..243b3db 100644
--- a/core/bmi/src/ol_fw.c
+++ b/core/bmi/src/ol_fw.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -376,18 +376,22 @@
|| chip_id == AR6320_REV1_3_VERSION
|| chip_id == AR6320_REV2_1_VERSION)) {
+ bin_off = sizeof(SIGN_HEADER_T);
status = bmi_sign_stream_start(address,
(uint8_t *)fw_entry->data,
- sizeof(SIGN_HEADER_T), ol_ctx);
+ bin_off, ol_ctx);
if (status != EOK) {
BMI_ERR("unable to start sign stream");
status = -EINVAL;
goto end;
}
- bin_off = sizeof(SIGN_HEADER_T);
- bin_len = sign_header->rampatch_len
- - sizeof(SIGN_HEADER_T);
+ bin_len = sign_header->rampatch_len - bin_off;
+ if (bin_len <= 0 || bin_len > fw_entry_size - bin_off) {
+ BMI_ERR("Invalid sign header");
+ status = -EINVAL;
+ goto end;
+ }
} else {
bin_sign = false;
bin_off = 0;
@@ -418,7 +422,7 @@
bin_off += bin_len;
bin_len = sign_header->total_len - sign_header->rampatch_len;
- if (bin_len > 0) {
+ if (bin_len > 0 && bin_len <= fw_entry_size - bin_off) {
status = bmi_sign_stream_start(0,
(uint8_t *)fw_entry->data +
bin_off, bin_len, ol_ctx);
diff --git a/core/cds/inc/cds_ieee80211_common.h b/core/cds/inc/cds_ieee80211_common.h
index b3c036b..c9a3448 100644
--- a/core/cds/inc/cds_ieee80211_common.h
+++ b/core/cds/inc/cds_ieee80211_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011,2014-2015, 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011,2014-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1815,6 +1815,8 @@
#define IEEE80211_CCMP_HEADERLEN 8
#define IEEE80211_CCMP_MICLEN 8
+#define WLAN_IEEE80211_GCMP_HEADERLEN 8
+#define WLAN_IEEE80211_GCMP_MICLEN 16
/*
* 802.11w defines a MMIE chunk to be attached at the end of
diff --git a/core/cds/inc/cds_utils.h b/core/cds/inc/cds_utils.h
index 46e24b5..d5d15f3 100644
--- a/core/cds/inc/cds_utils.h
+++ b/core/cds/inc/cds_utils.h
@@ -168,6 +168,27 @@
bool cds_attach_mmie(uint8_t *igtk, uint8_t *ipn, uint16_t key_id,
uint8_t *frm, uint8_t *efrm, uint16_t frmLen);
uint8_t cds_get_mmie_size(void);
+
+/**
+ * cds_is_gmac_mmie_valid: Validates GMAC MIC
+ * @igtk: integrity group temporal key
+ * @ipn: IGTK packet number
+ * @frm: IEEE 802.11 frame
+ * @efrm: End of frame
+ * @key_length: Length of IGTK
+ *
+ * Return: True if MIC validation is successful, false otherwise
+ */
+bool cds_is_gmac_mmie_valid(uint8_t *igtk, uint8_t *ipn, uint8_t *frm,
+ uint8_t *efrm, uint16_t key_length);
+
+/**
+ * cds_get_gmac_mmie_size: Gives length of GMAC MMIE size
+ *
+ * Return: Size of MMIE for GMAC
+ */
+uint8_t cds_get_gmac_mmie_size(void);
+
#endif /* WLAN_FEATURE_11W */
QDF_STATUS sme_send_flush_logs_cmd_to_fw(tpAniSirGlobal pMac);
static inline void cds_host_diag_log_work(qdf_wake_lock_t *lock, uint32_t msec,
diff --git a/core/cds/src/cds_utils.c b/core/cds/src/cds_utils.c
index bf207f3..cde0bb4 100644
--- a/core/cds/src/cds_utils.c
+++ b/core/cds/src/cds_utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -61,6 +61,8 @@
#include <crypto/aes.h>
#include "cds_ieee80211_common.h"
+#include <qdf_crypto.h>
+
/*----------------------------------------------------------------------------
* Preprocessor Definitions and Constants
* -------------------------------------------------------------------------*/
@@ -68,6 +70,7 @@
#define IV_SIZE_AES_128 16
#define CMAC_IPN_LEN 6
#define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */
+#define GMAC_NONCE_LEN 12
/*----------------------------------------------------------------------------
* Type Declarations
@@ -565,6 +568,139 @@
return !ret ? true : false;
}
+#if defined(WLAN_FEATURE_GMAC) && \
+ (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+uint8_t cds_get_gmac_mmie_size(void)
+{
+ return sizeof(struct ieee80211_mmie_16);
+}
+#else
+uint8_t cds_get_gmac_mmie_size(void)
+{
+ return 0;
+}
+#endif
+
+#ifdef WLAN_FEATURE_GMAC
+/**
+ * ipn_swap: Swaps ipn
+ * @d: destination pointer
+ * @s: source pointer
+ *
+ * Return: None
+ */
+static inline void ipn_swap(u8 *d, const u8 *s)
+{
+ *d++ = s[5];
+ *d++ = s[4];
+ *d++ = s[3];
+ *d++ = s[2];
+ *d++ = s[1];
+ *d = s[0];
+}
+#endif
+
+#if defined(WLAN_FEATURE_GMAC) && \
+ (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+bool cds_is_gmac_mmie_valid(uint8_t *igtk, uint8_t *ipn, uint8_t *frm,
+ uint8_t *efrm, uint16_t key_length)
+{
+ struct ieee80211_mmie_16 *mmie;
+ struct ieee80211_frame *wh;
+ uint8_t rx_ipn[6], aad[AAD_LEN], mic[IEEE80211_MMIE_GMAC_MICLEN];
+ uint16_t data_len;
+ uint8_t gmac_nonce[GMAC_NONCE_LEN];
+ uint8_t iv[AES_BLOCK_SIZE] = {0};
+ int ret;
+
+ /* Check if frame is invalid length */
+ if ((efrm < frm) || ((efrm - frm) < sizeof(*wh))) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "Invalid frame length");
+ return false;
+ }
+
+ mmie = (struct ieee80211_mmie_16 *)(efrm - sizeof(*mmie));
+
+ /* Check Element ID */
+ if ((mmie->element_id != IEEE80211_ELEMID_MMIE) ||
+ (mmie->length != (sizeof(*mmie) - 2))) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "IE is not Mgmt MIC IE or Invalid length");
+ /* IE is not Mgmt MIC IE or invalid length */
+ return false;
+ }
+
+ /* Validate IPN */
+ ipn_swap(rx_ipn, mmie->sequence_number);
+ if (qdf_mem_cmp(rx_ipn, ipn, IEEE80211_MMIE_IPNLEN) <= 0) {
+ /* Replay error */
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
+ "Replay error mmie ipn %02X %02X %02X %02X %02X %02X"
+ " drvr ipn %02X %02X %02X %02X %02X %02X",
+ rx_ipn[0], rx_ipn[1], rx_ipn[2], rx_ipn[3], rx_ipn[4],
+ rx_ipn[5], ipn[0], ipn[1], ipn[2], ipn[3], ipn[4],
+ ipn[5]);
+ return false;
+ }
+
+ /* Construct AAD */
+ wh = (struct ieee80211_frame *)frm;
+
+ /* Generate AAD: FC(masked) || A1 || A2 || A3 */
+ /* FC type/subtype */
+ aad[0] = wh->i_fc[0];
+ /* Mask FC Retry, PwrMgt, MoreData flags to zero */
+ aad[1] = wh->i_fc[1] & ~(IEEE80211_FC1_RETRY | IEEE80211_FC1_PWR_MGT |
+ IEEE80211_FC1_MORE_DATA);
+ /* A1 || A2 || A3 */
+ qdf_mem_copy(aad + 2, wh->i_addr_all, 3 * IEEE80211_ADDR_LEN);
+
+ data_len = efrm - (uint8_t *) (wh + 1) - IEEE80211_MMIE_GMAC_MICLEN;
+
+ /* IV */
+ qdf_mem_copy(gmac_nonce, wh->i_addr2, IEEE80211_ADDR_LEN);
+ qdf_mem_copy(gmac_nonce + IEEE80211_ADDR_LEN, rx_ipn,
+ IEEE80211_MMIE_IPNLEN);
+ qdf_mem_copy(iv, gmac_nonce, GMAC_NONCE_LEN);
+ iv[AES_BLOCK_SIZE - 1] = 0x01;
+
+ ret = qdf_crypto_aes_gmac(igtk, key_length, iv, aad,
+ (uint8_t *) (wh + 1), data_len, mic);
+ if (ret) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "qdf_crypto_aes_gmac failed %d", ret);
+ return false;
+ }
+
+ if (qdf_mem_cmp(mic, mmie->mic, IEEE80211_MMIE_GMAC_MICLEN) != 0) {
+ /* MMIE MIC mismatch */
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
+ "BC/MC MGMT frame MMIE MIC check Failed"
+ " rmic %02X %02X %02X %02X %02X %02X %02X %02X"
+ " %02X %02X %02X %02X %02X %02X %02X %02X",
+ mmie->mic[0], mmie->mic[1], mmie->mic[2],
+ mmie->mic[3], mmie->mic[4], mmie->mic[5],
+ mmie->mic[6], mmie->mic[7], mmie->mic[8],
+ mmie->mic[9], mmie->mic[10], mmie->mic[11],
+ mmie->mic[12], mmie->mic[13], mmie->mic[14],
+ mmie->mic[15]);
+ return false;
+ }
+
+ /* Update IPN */
+ qdf_mem_copy(ipn, rx_ipn, IEEE80211_MMIE_IPNLEN);
+
+ return true;
+}
+#else
+bool cds_is_gmac_mmie_valid(uint8_t *igtk, uint8_t *ipn, uint8_t *frm,
+ uint8_t *efrm, uint16_t key_length)
+{
+ return false;
+}
+#endif
+
#endif /* WLAN_FEATURE_11W */
uint32_t cds_chan_to_freq(uint8_t chan)
diff --git a/core/dp/ol/inc/ol_htt_rx_api.h b/core/dp/ol/inc/ol_htt_rx_api.h
index 950751a..85dd809 100644
--- a/core/dp/ol/inc/ol_htt_rx_api.h
+++ b/core/dp/ol/inc/ol_htt_rx_api.h
@@ -815,6 +815,12 @@
* Return: number of buffers actually replenished
*/
int htt_rx_msdu_buff_in_order_replenish(htt_pdev_handle pdev, uint32_t num);
+#else
+static inline
+int htt_rx_msdu_buff_in_order_replenish(htt_pdev_handle pdev, uint32_t num)
+{
+ return 0;
+}
#endif
/**
diff --git a/core/dp/txrx/ol_rx_defrag.c b/core/dp/txrx/ol_rx_defrag.c
index 4496b21..60ec626 100644
--- a/core/dp/txrx/ol_rx_defrag.c
+++ b/core/dp/txrx/ol_rx_defrag.c
@@ -316,6 +316,26 @@
#endif
+#ifndef CONFIG_HL_SUPPORT
+static int ol_rx_frag_get_inord_msdu_cnt(qdf_nbuf_t rx_ind_msg)
+{
+ uint32_t *msg_word;
+ uint8_t *rx_ind_data;
+ uint32_t msdu_cnt;
+
+ rx_ind_data = qdf_nbuf_data(rx_ind_msg);
+ msg_word = (uint32_t *)rx_ind_data;
+ msdu_cnt = HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(*(msg_word + 1));
+
+ return msdu_cnt;
+}
+#else
+static int ol_rx_frag_get_inord_msdu_cnt(qdf_nbuf_t rx_ind_msg)
+{
+ return 0;
+}
+#endif
+
/*
* Process incoming fragments
*/
@@ -353,7 +373,10 @@
* separate from normal frames
*/
ol_rx_reorder_flush_frag(htt_pdev, peer, tid, seq_num_start);
+ } else {
+ msdu_count = ol_rx_frag_get_inord_msdu_cnt(rx_frag_ind_msg);
}
+
pktlog_bit =
(htt_rx_amsdu_rx_in_order_get_pktlog(rx_frag_ind_msg) == 0x01);
ret = htt_rx_frag_pop(htt_pdev, rx_frag_ind_msg, &head_msdu,
@@ -389,7 +412,11 @@
htt_rx_desc_frame_free(htt_pdev, head_msdu);
}
/* request HTT to provide new rx MSDU buffers for the target to fill. */
- htt_rx_msdu_buff_replenish(htt_pdev);
+ if (ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev) &&
+ !pdev->cfg.is_high_latency)
+ htt_rx_msdu_buff_in_order_replenish(htt_pdev, msdu_count);
+ else
+ htt_rx_msdu_buff_replenish(htt_pdev);
}
/*
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 8f880d2..30b1cd3 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -12862,6 +12862,29 @@
/*
* <ini>
+ * sae_enabled - Enable/Disable SAE support in driver
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable SAE support in driver
+ * Driver will update config to supplicant based on this config.
+ *
+ * Related: None
+ *
+ * Supported Feature: SAE
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_IS_SAE_ENABLED_NAME "sae_enabled"
+#define CFG_IS_SAE_ENABLED_DEFAULT (1)
+#define CFG_IS_SAE_ENABLED_MIN (0)
+#define CFG_IS_SAE_ENABLED_MAX (1)
+
+/*
+ * <ini>
* chan_width_weightage - Channel Width Weightage to calculate best candidate
* @Min: 0
* @Max: 100
@@ -14080,7 +14103,7 @@
#define CFG_ENABLE_GCMP_NAME "gcmp_enabled"
#define CFG_ENABLE_GCMP_MIN (0)
#define CFG_ENABLE_GCMP_MAX (1)
-#define CFG_ENABLE_GCMP_DEFAULT (0)
+#define CFG_ENABLE_GCMP_DEFAULT (1)
/*
* <ini>
@@ -15277,6 +15300,9 @@
bool enable_rtt_mac_randomization;
uint32_t enable_secondary_rate;
bool is_unit_test_framework_enabled;
+#ifdef WLAN_FEATURE_SAE
+ bool is_sae_enabled;
+#endif
};
#define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 1553d5f..8882266 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -798,10 +798,9 @@
* @adapter: Adapter address
* @scan_request: scan request holder
* @scan_id: scan identifier used across host layers which is generated at WMI
+ * @cookie: scan request identifier sent to userspace
* @source: scan request originator (NL/Vendor scan)
* @timestamp: scan request timestamp
- * @inactivity_timer: scan inactivity timer
- * @scan_req_flags: scan request flags
*
* Scan request linked list element
*/
@@ -3065,15 +3064,6 @@
void hdd_driver_memdump_deinit(void);
/**
- * hdd_is_cli_iface_up() - check if there is any cli iface up
- * @hdd_ctx: HDD context
- *
- * Return: return true if there is any cli iface(STA/P2P_CLI) is up
- * else return false
- */
-bool hdd_is_cli_iface_up(hdd_context_t *hdd_ctx);
-
-/**
* hdd_get_nud_stats_cb() - callback api to update the stats received from FW
* @data: pointer to hdd context.
* @rsp: pointer to data received from FW.
diff --git a/core/hdd/inc/wlan_hdd_softap_tx_rx.h b/core/hdd/inc/wlan_hdd_softap_tx_rx.h
index 43cbd0a..5fd7ee5 100644
--- a/core/hdd/inc/wlan_hdd_softap_tx_rx.h
+++ b/core/hdd/inc/wlan_hdd_softap_tx_rx.h
@@ -38,7 +38,7 @@
#include <cdp_txrx_peer_ops.h>
netdev_tx_t hdd_softap_hard_start_xmit(struct sk_buff *skb,
- struct net_device *dev);
+ struct net_device *dev);
void hdd_softap_tx_timeout(struct net_device *dev);
QDF_STATUS hdd_softap_init_tx_rx(hdd_adapter_t *pAdapter);
QDF_STATUS hdd_softap_deinit_tx_rx(hdd_adapter_t *pAdapter);
diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c
index b55d516..632ea39 100644
--- a/core/hdd/src/wlan_hdd_assoc.c
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -119,6 +119,23 @@
uint8_t ccp_rsn_oui_10[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x10};
uint8_t ccp_rsn_oui_11[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x11};
#endif
+static const
+uint8_t ccp_rsn_oui_12[HDD_RSN_OUI_SIZE] = {0x50, 0x6F, 0x9A, 0x02};
+
+static const
+uint8_t ccp_rsn_oui_0b[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x0B};
+static const
+uint8_t ccp_rsn_oui_0c[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x0C};
+
+#ifdef WLAN_FEATURE_OWE
+/* OWE https://tools.ietf.org/html/rfc8110 */
+uint8_t ccp_rsn_oui_18[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x12};
+#endif
+
+#ifdef WLAN_FEATURE_SAE
+uint8_t ccp_rsn_oui_80[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x08};
+uint8_t ccp_rsn_oui_90[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x09};
+#endif
/* Offset where the EID-Len-IE, start. */
#define FT_ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2) */
@@ -140,6 +157,55 @@
SIR_MAC_VHT_OPERATION_EID,
};
+#ifdef WLAN_FEATURE_SAE
+/**
+ * wlan_hdd_sae_callback() - Sends SAE info to supplicant
+ * @adapter: pointer adapter context
+ * @roam_info: pointer to roam info
+ *
+ * This API is used to send required SAE info to trigger SAE in supplicant.
+ *
+ * Return: None
+ */
+static void wlan_hdd_sae_callback(hdd_adapter_t *adapter,
+ tCsrRoamInfo *roam_info)
+{
+ hdd_context_t *hdd_ctx = adapter->pHddCtx;
+ int flags;
+ struct sir_sae_info *sae_info = roam_info->sae_info;
+ struct cfg80211_external_auth_params params = {0};
+
+ if (wlan_hdd_validate_context(hdd_ctx))
+ return;
+
+ if (!sae_info) {
+ hdd_err("SAE info in NULL");
+ return;
+ }
+
+ flags = cds_get_gfp_flags();
+
+ params.key_mgmt_suite = 0x00;
+ params.key_mgmt_suite |= 0x0F << 8;
+ params.key_mgmt_suite |= 0xAC << 16;
+ params.key_mgmt_suite |= 0x8 << 24;
+
+ params.action = NL80211_EXTERNAL_AUTH_START;
+ qdf_mem_copy(params.bssid, sae_info->peer_mac_addr.bytes,
+ QDF_MAC_ADDR_SIZE);
+ qdf_mem_copy(params.ssid.ssid, sae_info->ssid.ssId,
+ sae_info->ssid.length);
+ params.ssid.ssid_len = sae_info->ssid.length;
+
+ cfg80211_external_auth_request(adapter->dev, ¶ms, flags);
+ hdd_debug("SAE: sent cmd");
+}
+#else
+static inline void wlan_hdd_sae_callback(hdd_adapter_t *adapter,
+ tCsrRoamInfo *roam_info)
+{ }
+#endif
+
/**
* hdd_conn_set_authenticated() - set authentication state
* @pAdapter: pointer to the adapter
@@ -884,6 +950,8 @@
} else {
hdd_sta_ctx->conn_info.conn_flag.vht_op_present = false;
}
+ qdf_mem_zero(&hdd_sta_ctx->ibss_enc_key,
+ sizeof(hdd_sta_ctx->ibss_enc_key));
}
/**
@@ -1689,6 +1757,7 @@
hdd_wmm_adapter_clear(pAdapter);
sme_ft_reset(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId);
+ sme_reset_key(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId);
if (hdd_remove_beacon_filter(pAdapter) != 0)
hdd_err("hdd_remove_beacon_filter() failed");
@@ -2737,64 +2806,78 @@
pHddCtx->wiphy,
bss);
}
+
+ /* Association Response */
+ pFTAssocRsp =
+ (u8 *) (pRoamInfo->pbFrames +
+ pRoamInfo->nBeaconLength +
+ pRoamInfo->nAssocReqLength);
+ if (pFTAssocRsp != NULL) {
+ /*
+ * pFTAssocRsp needs to point to the IEs
+ */
+ pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
+ hdd_debug("AssocRsp is now at %02x%02x",
+ (unsigned int)pFTAssocRsp[0],
+ (unsigned int)pFTAssocRsp[1]);
+ assocRsplen =
+ pRoamInfo->nAssocRspLength -
+ FT_ASSOC_RSP_IES_OFFSET;
+
+ hdd_debug("assocRsplen %d", assocRsplen);
+ hdd_debug("Assoc Rsp IE dump");
+ QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
+ QDF_TRACE_LEVEL_DEBUG,
+ pFTAssocRsp,
+ assocRsplen);
+ } else {
+ hdd_debug("AssocRsp is NULL");
+ assocRsplen = 0;
+ }
+
+ /* Association Request */
+ pFTAssocReq = (u8 *) (pRoamInfo->pbFrames +
+ pRoamInfo->nBeaconLength);
+ if (pFTAssocReq != NULL) {
+ if (!ft_carrier_on) {
+ /*
+ * pFTAssocReq needs to point to
+ * the IEs
+ */
+ pFTAssocReq +=
+ FT_ASSOC_REQ_IES_OFFSET;
+ hdd_debug("pFTAssocReq is now at %02x%02x",
+ (unsigned int)
+ pFTAssocReq[0],
+ (unsigned int)
+ pFTAssocReq[1]);
+ assocReqlen =
+ pRoamInfo->nAssocReqLength -
+ FT_ASSOC_REQ_IES_OFFSET;
+ } else {
+ /*
+ * This should contain only the
+ * FTIEs
+ */
+ assocReqlen =
+ pRoamInfo->nAssocReqLength;
+ }
+
+ hdd_debug("assocReqlen %d", assocReqlen);
+ hdd_debug("Assoc/Reassoc Req IE dump");
+ QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
+ QDF_TRACE_LEVEL_DEBUG,
+ pFTAssocReq,
+ assocReqlen);
+ } else {
+ hdd_debug("AssocReq is NULL");
+ assocReqlen = 0;
+ }
+
if (pRoamInfo->u.pConnectedProfile->AuthType ==
eCSR_AUTH_TYPE_FT_RSN
|| pRoamInfo->u.pConnectedProfile->AuthType ==
eCSR_AUTH_TYPE_FT_RSN_PSK) {
-
- /* Association Response */
- pFTAssocRsp =
- (u8 *) (pRoamInfo->pbFrames +
- pRoamInfo->nBeaconLength +
- pRoamInfo->nAssocReqLength);
- if (pFTAssocRsp != NULL) {
- /*
- * pFTAssocRsp needs to point to the IEs
- */
- pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
- hdd_debug("AssocRsp is now at %02x%02x",
- (unsigned int)pFTAssocRsp[0],
- (unsigned int)pFTAssocRsp[1]);
- assocRsplen =
- pRoamInfo->nAssocRspLength -
- FT_ASSOC_RSP_IES_OFFSET;
- } else {
- hdd_debug("AssocRsp is NULL");
- assocRsplen = 0;
- }
-
- /* Association Request */
- pFTAssocReq = (u8 *) (pRoamInfo->pbFrames +
- pRoamInfo->nBeaconLength);
- if (pFTAssocReq != NULL) {
- if (!ft_carrier_on) {
- /*
- * pFTAssocReq needs to point to
- * the IEs
- */
- pFTAssocReq +=
- FT_ASSOC_REQ_IES_OFFSET;
- hdd_debug("pFTAssocReq is now at %02x%02x",
- (unsigned int)
- pFTAssocReq[0],
- (unsigned int)
- pFTAssocReq[1]);
- assocReqlen =
- pRoamInfo->nAssocReqLength -
- FT_ASSOC_REQ_IES_OFFSET;
- } else {
- /*
- * This should contain only the
- * FTIEs
- */
- assocReqlen =
- pRoamInfo->nAssocReqLength;
- }
- } else {
- hdd_debug("AssocReq is NULL");
- assocReqlen = 0;
- }
-
if (ft_carrier_on) {
if (!hddDisconInProgress &&
pRoamInfo->pBssDesc) {
@@ -2824,18 +2907,6 @@
(pAdapter->wdev.wiphy,
(int)pRoamInfo->pBssDesc->
channelId);
- hdd_debug(
- "assocReqlen %d assocRsplen %d",
- assocReqlen,
- assocRsplen);
-
- hdd_debug(
- "Reassoc Req IE dump");
- QDF_TRACE_HEX_DUMP(
- QDF_MODULE_ID_HDD,
- QDF_TRACE_LEVEL_DEBUG,
- pFTAssocReq,
- assocReqlen);
roam_bss =
hdd_cfg80211_get_bss(
pAdapter->wdev.wiphy,
@@ -2942,10 +3013,10 @@
pRoamInfo->
bssid.bytes,
pRoamInfo,
- reqRsnIe,
- reqRsnLength,
- rspRsnIe,
- rspRsnLength,
+ pFTAssocReq,
+ assocReqlen,
+ pFTAssocRsp,
+ assocRsplen,
WLAN_STATUS_SUCCESS,
GFP_KERNEL,
false,
@@ -3100,7 +3171,9 @@
pRoamInfo ?
pRoamInfo->bssid.bytes :
pWextState->req_bssId.bytes);
- connect_timeout = true;
+ if (roamResult !=
+ eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE)
+ connect_timeout = true;
}
/*
@@ -3174,6 +3247,8 @@
timeout_reason);
}
hdd_clear_roam_profile_ie(pAdapter);
+ sme_reset_key(WLAN_HDD_GET_HAL_CTX(pAdapter),
+ pAdapter->sessionId);
} else if ((eCSR_ROAM_CANCELLED == roamStatus
&& !hddDisconInProgress)) {
hdd_connect_result(dev,
@@ -5060,13 +5135,18 @@
case eCSR_ROAM_NAPI_OFF:
hdd_debug("After Roam Synch Comp: NAPI Serialize OFF");
hdd_napi_serialize(0);
- hdd_set_roaming_in_progress(false);
- if (roamResult == eCSR_ROAM_RESULT_FAILURE)
+ if (roamResult == eCSR_ROAM_RESULT_FAILURE) {
pAdapter->roam_ho_fail = true;
- else
+ hdd_set_roaming_in_progress(false);
+ } else {
pAdapter->roam_ho_fail = false;
+ }
complete(&pAdapter->roaming_comp_var);
break;
+ case eCSR_ROAM_SYNCH_COMPLETE:
+ hdd_debug("LFR3: Roam synch complete");
+ hdd_set_roaming_in_progress(false);
+ break;
case eCSR_ROAM_SHOULD_ROAM:
/* notify apps that we can't pass traffic anymore */
hdd_info("Disabling queues");
@@ -5340,6 +5420,10 @@
complete(&pAdapter->roaming_comp_var);
schedule_delayed_work(&pHddCtx->roc_req_work, 0);
break;
+ case eCSR_ROAM_SAE_COMPUTE:
+ if (pRoamInfo)
+ wlan_hdd_sae_callback(pAdapter, pRoamInfo);
+ break;
default:
break;
@@ -5374,6 +5458,48 @@
}
#endif
+#ifdef WLAN_FEATURE_OWE
+/**
+ * hdd_translate_owe_rsn_to_csr_auth() - Translate OWE RSN to CSR auth type
+ * @auth_suite: auth suite
+ * @auth_type: pointer to eCsrAuthType
+ *
+ * Return: None
+ */
+static void hdd_translate_owe_rsn_to_csr_auth(int8_t auth_suite[4],
+ eCsrAuthType *auth_type)
+{
+ if (memcmp(auth_suite, ccp_rsn_oui_18, 4) == 0)
+ *auth_type = eCSR_AUTH_TYPE_OWE;
+}
+#else
+static inline void hdd_translate_owe_rsn_to_csr_auth(int8_t auth_suite[4],
+ eCsrAuthType *auth_type)
+{
+}
+#endif
+
+#ifdef WLAN_FEATURE_SAE
+/**
+ * hdd_translate_sae_rsn_to_csr_auth() - Translate SAE RSN to CSR auth type
+ * @auth_suite: auth suite
+ * @auth_type: pointer to eCsrAuthType
+ *
+ * Return: None
+ */
+static void hdd_translate_sae_rsn_to_csr_auth(int8_t auth_suite[4],
+ eCsrAuthType *auth_type)
+{
+ if (qdf_mem_cmp(auth_suite, ccp_rsn_oui_80, 4) == 0)
+ *auth_type = eCSR_AUTH_TYPE_SAE;
+}
+#else
+static inline void hdd_translate_sae_rsn_to_csr_auth(int8_t auth_suite[4],
+ eCsrAuthType *auth_type)
+{
+}
+#endif
+
/**
* hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type
* @auth_suite: auth suite
@@ -5407,8 +5533,18 @@
auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
} else
#endif
- {
+ if (memcmp(auth_suite, ccp_rsn_oui_0b, 4) == 0) {
+ /* Check for Suite B EAP 256 */
+ auth_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA256;
+ } else if (memcmp(auth_suite, ccp_rsn_oui_0c, 4) == 0) {
+ /* Check for Suite B EAP 384 */
+ auth_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA384;
+ } else if (memcmp(auth_suite, ccp_rsn_oui_12, 4) == 0) {
+ auth_type = eCSR_AUTH_TYPE_DPP_RSN;
+ } else {
hdd_translate_fils_rsn_to_csr_auth(auth_suite, &auth_type);
+ hdd_translate_owe_rsn_to_csr_auth(auth_suite, &auth_type);
+ hdd_translate_sae_rsn_to_csr_auth(auth_suite, &auth_type);
}
hdd_debug("auth_type: %d", auth_type);
return auth_type;
@@ -5810,6 +5946,33 @@
}
#endif
+#ifdef WLAN_FEATURE_OWE
+/**
+ * hdd_check_is_owe_auth_type() - This API checks whether a give
+ * auth type is OWE if yes, sets it in profile.
+ * @rsn_auth_type: auth type
+ *
+ * Return: true if OWE auth else false
+ */
+static bool hdd_check_is_owe_auth_type(tCsrRoamProfile *roam_profile,
+ eCsrAuthType rsn_auth_type)
+{
+ bool is_owe_rsn = false;
+
+ if (rsn_auth_type == eCSR_AUTH_TYPE_OWE)
+ is_owe_rsn = true;
+
+ return is_owe_rsn;
+}
+#else
+static bool hdd_check_is_owe_auth_type(tCsrRoamProfile *roam_profile,
+ eCsrAuthType rsn_auth_type)
+{
+ return false;
+}
+#endif
+
+
/**
* hdd_set_csr_auth_type() - set csr auth type
* @pAdapter: pointer to adapter
@@ -5824,8 +5987,9 @@
hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
pRoamProfile->AuthType.numEntries = 1;
- hdd_debug("pHddStaCtx->conn_info.authType = %d",
- pHddStaCtx->conn_info.authType);
+ hdd_debug("authType = %d RSNAuthType %d wpa_version %d",
+ pHddStaCtx->conn_info.authType, RSNAuthType,
+ pWextState->wpaVersion);
switch (pHddStaCtx->conn_info.authType) {
case eCSR_AUTH_TYPE_OPEN_SYSTEM:
@@ -5881,8 +6045,10 @@
eCSR_AUTH_TYPE_CCKM_RSN;
} else
#endif
-
- if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
+ if (RSNAuthType == eCSR_AUTH_TYPE_DPP_RSN) {
+ pRoamProfile->AuthType.authType[0] =
+ eCSR_AUTH_TYPE_DPP_RSN;
+ } else if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
((pWextState->
authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
== IW_AUTH_KEY_MGMT_802_1X)) {
@@ -5914,6 +6080,28 @@
hdd_debug("updated profile authtype as %d",
RSNAuthType);
+ } else if (hdd_check_is_owe_auth_type(
+ pRoamProfile, RSNAuthType)) {
+ pRoamProfile->AuthType.authType[0] =
+ RSNAuthType;
+ hdd_debug("updated profile authtype as %d",
+ RSNAuthType);
+ } else if ((RSNAuthType ==
+ eCSR_AUTH_TYPE_SUITEB_EAP_SHA256) &&
+ ((pWextState->
+ authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
+ == IW_AUTH_KEY_MGMT_802_1X)) {
+ /* Suite B EAP SHA 256 */
+ pRoamProfile->AuthType.authType[0] =
+ eCSR_AUTH_TYPE_SUITEB_EAP_SHA256;
+ } else if ((RSNAuthType ==
+ eCSR_AUTH_TYPE_SUITEB_EAP_SHA384) &&
+ ((pWextState->
+ authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
+ == IW_AUTH_KEY_MGMT_802_1X)) {
+ /* Suite B EAP SHA 384 */
+ pRoamProfile->AuthType.authType[0] =
+ eCSR_AUTH_TYPE_SUITEB_EAP_SHA384;
} else if ((pWextState->
authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
== IW_AUTH_KEY_MGMT_802_1X) {
@@ -5935,6 +6123,11 @@
pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
break;
+
+ case eCSR_AUTH_TYPE_SAE:
+ pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SAE;
+ break;
+
default:
#ifdef FEATURE_WLAN_ESE
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index eed1302..ab3d073 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -5567,6 +5567,14 @@
CFG_ENABLE_UINT_TEST_FRAMEWORK_DEFAULT,
CFG_ENABLE_UNIT_TEST_FRAMEWORK_MIN,
CFG_ENABLE_UNIT_TEST_FRAMEWORK_MAX),
+#ifdef WLAN_FEATURE_SAE
+ REG_VARIABLE(CFG_IS_SAE_ENABLED_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, is_sae_enabled,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_IS_SAE_ENABLED_DEFAULT,
+ CFG_IS_SAE_ENABLED_MIN,
+ CFG_IS_SAE_ENABLED_MAX),
+#endif
};
/**
@@ -6502,6 +6510,19 @@
hdd_ctx->config->neighbor_report_offload_max_req_cap);
}
+#ifdef WLAN_FEATURE_SAE
+static void hdd_cfg_print_sae(hdd_context_t *hdd_ctx)
+{
+ hdd_debug("Name = [%s] value = [%u]",
+ CFG_IS_SAE_ENABLED_NAME,
+ hdd_ctx->config->is_sae_enabled);
+}
+#else
+static void hdd_cfg_print_sae(hdd_context_t *hdd_ctx)
+{
+}
+#endif
+
/**
* hdd_cfg_print() - print the hdd configuration
* @iniTable: pointer to hdd context
@@ -7451,6 +7472,7 @@
hdd_debug("Name = [%s] value = [0x%x]",
CFG_ENABLE_UNIT_TEST_FRAMEWORK_NAME,
pHddCtx->config->is_unit_test_framework_enabled);
+ hdd_cfg_print_sae(pHddCtx);
}
/**
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index 70cb733..5d5bd94 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -178,11 +178,6 @@
*/
#define WLAN_DEAUTH_DPTRACE_DUMP_COUNT 100
-/*
- * Count to ratelimit the HDD logs during NL parsing
- */
-#define HDD_NL_ERR_RATE_LIMIT 5
-
static const u32 hdd_gcmp_cipher_suits[] = {
WLAN_CIPHER_SUITE_GCMP,
WLAN_CIPHER_SUITE_GCMP_256,
@@ -206,6 +201,11 @@
#endif
#ifdef WLAN_FEATURE_11W
WLAN_CIPHER_SUITE_AES_CMAC,
+#if defined(WLAN_FEATURE_GMAC) && \
+ (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+ WLAN_CIPHER_SUITE_BIP_GMAC_128,
+ WLAN_CIPHER_SUITE_BIP_GMAC_256,
+#endif
#endif
};
@@ -349,7 +349,8 @@
[NL80211_IFTYPE_STATION] = {
.tx = 0xffff,
.rx = BIT(SIR_MAC_MGMT_ACTION) |
- BIT(SIR_MAC_MGMT_PROBE_REQ),
+ BIT(SIR_MAC_MGMT_PROBE_REQ) |
+ BIT(SIR_MAC_MGMT_AUTH),
},
[NL80211_IFTYPE_AP] = {
.tx = 0xffff,
@@ -2201,6 +2202,8 @@
if (hdd_scan_random_mac_addr_supported())
fset |= WIFI_FEATURE_SCAN_RAND;
+ fset |= WIFI_FEATURE_P2P_RAND_MAC;
+
skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
NLMSG_HDRLEN);
if (!skb) {
@@ -4927,6 +4930,8 @@
qdf_mem_copy(local_pmk, data, data_len);
sme_roam_set_psk_pmk(WLAN_HDD_GET_HAL_CTX(hdd_adapter_ptr),
hdd_adapter_ptr->sessionId, local_pmk, data_len);
+ qdf_mem_zero(&local_pmk, SIR_ROAM_SCAN_PSK_SIZE);
+
return 0;
}
@@ -5768,12 +5773,6 @@
override_li = nla_get_u32(
tb[QCA_WLAN_VENDOR_ATTR_CONFIG_LISTEN_INTERVAL]);
- if (override_li > CFG_ENABLE_DYNAMIC_DTIM_MAX) {
- hdd_err_ratelimited(HDD_NL_ERR_RATE_LIMIT,
- "Invalid value for listen interval - %d",
- override_li);
- return -EINVAL;
- }
status = sme_override_listen_interval(hdd_ctx->hHal,
adapter->sessionId,
override_li);
@@ -6398,7 +6397,7 @@
QDF_STATUS status;
hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
- struct sir_wifi_start_log start_log = { 0 };
+ struct sir_wifi_start_log start_log;
ENTER_DEV(wdev->netdev);
@@ -6450,8 +6449,6 @@
tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
hdd_debug("is_iwpriv_command =%d", start_log.is_iwpriv_command);
- start_log.user_triggered = 1;
-
/* size is buff size which can be set using iwpriv command*/
start_log.size = 0;
start_log.is_pktlog_buff_clear = false;
@@ -9219,6 +9216,8 @@
for (ch_idx = channel_list->avoidFreqRange[range_idx].startFreq;
ch_idx <= channel_list->avoidFreqRange[range_idx].endFreq;
ch_idx++) {
+ if (INVALID_CHANNEL == cds_get_channel_enum(ch_idx))
+ continue;
for (unsafe_channel_index = 0;
unsafe_channel_index < unsafe_channel_count;
unsafe_channel_index++) {
@@ -10821,11 +10820,17 @@
*
* Return: Byte following constructed DNS name
*/
-static uint8_t *hdd_dns_make_name_query(const uint8_t *string, uint8_t *buf)
+static uint8_t *hdd_dns_make_name_query(const uint8_t *string,
+ uint8_t *buf, uint8_t len)
{
uint8_t *length_byte = buf++;
uint8_t c;
+ if (string[len - 1]) {
+ hdd_debug("DNS name is not null terminated");
+ return NULL;
+ }
+
while ((c = *(string++))) {
if (c == '.') {
*length_byte = buf - length_byte - 1;
@@ -10914,8 +10919,12 @@
adapter->track_dns_domain_len =
nla_len(tb2[
STATS_DNS_DOMAIN_NAME]);
- hdd_dns_make_name_query(domain_name,
- adapter->dns_payload);
+ if (!hdd_dns_make_name_query(
+ domain_name,
+ adapter->dns_payload,
+ adapter->track_dns_domain_len))
+ adapter->track_dns_domain_len =
+ 0;
/* DNStracking isn't supported in FW. */
arp_stats_params->pkt_type_bitmap &=
~CONNECTIVITY_CHECK_SET_DNS;
@@ -13582,6 +13591,31 @@
{
}
#endif
+
+#if defined(WLAN_FEATURE_SAE) && \
+ defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
+/**
+ * wlan_hdd_cfg80211_set_wiphy_sae_feature() - Indicates support of SAE feature
+ * @wiphy: Pointer to wiphy
+ * @config: pointer to config
+ *
+ * This function is used to indicate the support of SAE
+ *
+ * Return: None
+ */
+static void wlan_hdd_cfg80211_set_wiphy_sae_feature(struct wiphy *wiphy,
+ struct hdd_config *config)
+{
+ if (config->is_sae_enabled)
+ wiphy->features |= NL80211_FEATURE_SAE;
+}
+#else
+static void wlan_hdd_cfg80211_set_wiphy_sae_feature(struct wiphy *wiphy,
+ struct hdd_config *config)
+{
+}
+#endif
+
/*
* FUNCTION: wlan_hdd_cfg80211_init
* This function is called by hdd_wlan_startup()
@@ -13648,6 +13682,8 @@
if (pCfg->is_fils_enabled)
wlan_hdd_cfg80211_set_wiphy_fils_feature(wiphy);
+ wlan_hdd_cfg80211_set_wiphy_sae_feature(wiphy, pCfg);
+
wlan_hdd_cfg80211_set_wiphy_scan_flags(wiphy);
hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
@@ -14587,6 +14623,7 @@
eCsrRoamBssType LastBSSType;
struct hdd_config *pConfig = NULL;
int status;
+ bool dev_flags = (ndev->flags & IFF_UP);
ENTER();
@@ -14658,10 +14695,13 @@
type, status);
return status;
}
- if (hdd_start_adapter(pAdapter)) {
- hdd_err("Failed to start adapter :%d",
- pAdapter->device_mode);
- return -EINVAL;
+
+ if (dev_flags) {
+ if (hdd_start_adapter(pAdapter)) {
+ hdd_err("Failed to start adapter:%d",
+ pAdapter->device_mode);
+ return -EINVAL;
+ }
}
goto done;
case NL80211_IFTYPE_AP:
@@ -14711,9 +14751,12 @@
hdd_set_ap_ops(pAdapter->dev);
- if (hdd_start_adapter(pAdapter)) {
- hdd_err("Error initializing the ap mode");
- return -EINVAL;
+ if (dev_flags) {
+ if (hdd_start_adapter(pAdapter)) {
+ hdd_err("Failed to start adapter:%d",
+ pAdapter->device_mode);
+ return -EINVAL;
+ }
}
/* Interface type changed update in wiphy structure */
if (wdev) {
@@ -14739,10 +14782,12 @@
type);
if (status != QDF_STATUS_SUCCESS)
return status;
- if (hdd_start_adapter(pAdapter)) {
- hdd_err("Failed to start adapter: %d",
- pAdapter->device_mode);
- return -EINVAL;
+ if (dev_flags) {
+ if (hdd_start_adapter(pAdapter)) {
+ hdd_err("Failed to start adapter:%d",
+ pAdapter->device_mode);
+ return -EINVAL;
+ }
}
goto done;
@@ -15349,6 +15394,15 @@
case WLAN_CIPHER_SUITE_AES_CMAC:
setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
break;
+#if defined(WLAN_FEATURE_GMAC) && \
+ (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+ case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+ setKey.encType = eCSR_ENCRYPT_TYPE_AES_GMAC_128;
+ break;
+ case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+ setKey.encType = eCSR_ENCRYPT_TYPE_AES_GMAC_256;
+ break;
+#endif
#endif
case WLAN_CIPHER_SUITE_GCMP:
setKey.encType = eCSR_ENCRYPT_TYPE_AES_GCMP;
@@ -15359,6 +15413,7 @@
default:
hdd_err("Unsupported cipher type: %u", params->cipher);
+ qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return -EOPNOTSUPP;
}
@@ -15379,6 +15434,7 @@
/* if a key is already installed, block all subsequent ones */
if (pAdapter->sessionCtx.station.ibss_enc_key_installed) {
hdd_debug("IBSS key installed already");
+ qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return 0;
}
@@ -15389,6 +15445,7 @@
if (0 != status) {
hdd_err("sme_roam_set_key failed, status: %d", status);
+ qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return -EINVAL;
}
/*Save the keys here and call sme_roam_set_key for setting
@@ -15397,6 +15454,7 @@
&setKey, sizeof(tCsrRoamSetKey));
pAdapter->sessionCtx.station.ibss_enc_key_installed = 1;
+ qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return status;
}
if ((pAdapter->device_mode == QDF_SAP_MODE) ||
@@ -15459,9 +15517,11 @@
pAdapter->sessionId, &setKey);
if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) {
hdd_debug("Update PreAuth Key success");
+ qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return 0;
} else if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) {
hdd_err("Update PreAuth Key failed");
+ qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return -EINVAL;
}
@@ -15473,6 +15533,7 @@
hdd_err("sme_roam_set_key failed, status: %d", status);
pHddStaCtx->roam_info.roamingState =
HDD_ROAM_STATE_NONE;
+ qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return -EINVAL;
}
@@ -15506,10 +15567,12 @@
hdd_err("sme_roam_set_key failed for group key (IBSS), returned %d", status);
pHddStaCtx->roam_info.roamingState =
HDD_ROAM_STATE_NONE;
+ qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return -EINVAL;
}
}
}
+ qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
EXIT();
return 0;
}
@@ -17081,6 +17144,12 @@
hdd_debug("set authentication type to FILS SHARED");
pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
break;
+
+ case NL80211_AUTHTYPE_SAE:
+ hdd_debug("set authentication type to SAE");
+ pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SAE;
+ break;
+
#endif
default:
hdd_err("Unsupported authentication type: %d", auth_type);
@@ -17359,6 +17428,7 @@
case WLAN_AKM_SUITE_PSK:
case WLAN_AKM_SUITE_PSK_SHA256:
case WLAN_AKM_SUITE_FT_PSK:
+ case WLAN_AKM_SUITE_DPP_RSN:
hdd_debug("setting key mgmt type to PSK");
pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
break;
@@ -17415,6 +17485,29 @@
eCSR_AUTH_TYPE_FT_FILS_SHA384;
break;
#endif
+
+#ifdef WLAN_FEATURE_OWE
+ case WLAN_AKM_SUITE_OWE:
+ hdd_debug("setting key mgmt type to OWE");
+ pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
+ break;
+#endif
+
+ case WLAN_AKM_SUITE_EAP_SHA256:
+ hdd_debug("setting key mgmt type to EAP_SHA256");
+ pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
+ break;
+
+ case WLAN_AKM_SUITE_EAP_SHA384:
+ hdd_debug("setting key mgmt type to EAP_SHA384");
+ pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
+ break;
+
+ case WLAN_AKM_SUITE_SAE:
+ hdd_debug("setting key mgmt type to SAE");
+ pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
+ break;
+
default:
hdd_err("Unsupported key mgmt type: %d", key_mgmt);
return -EINVAL;
@@ -17856,30 +17949,16 @@
/* Setting WAPI Mode to ON=1 */
pAdapter->wapi_info.nWapiMode = 1;
hdd_debug("WAPI MODE IS %u", pAdapter->wapi_info.nWapiMode);
- /* genie is pointing to data field of WAPI IE's buffer */
- tmp = (uint8_t *)genie;
- /* Validate length for Version(2 bytes) and Number
- * of AKM suite (2 bytes) in WAPI IE buffer, coming from
- * supplicant*/
- if (eLen < 4) {
- hdd_err("Invalid IE Len: %u", eLen);
- return -EINVAL;
- }
- tmp = tmp + 2; /* Skip Version */
+ tmp = (uint8_t *)ie;
+ tmp = tmp + 4; /* Skip element Id and Len, Version */
/* Get the number of AKM suite */
akmsuiteCount = WPA_GET_LE16(tmp);
/* Skip the number of AKM suite */
tmp = tmp + 2;
- /* Validate total length for WAPI IE's buffer */
- if (eLen < (4 + (akmsuiteCount * sizeof(uint32_t)))) {
- hdd_err("Invalid IE Len: %u", eLen);
- return -EINVAL;
- }
/* AKM suite list, each OUI contains 4 bytes */
akmlist = (uint32_t *)(tmp);
if (akmsuiteCount <= MAX_NUM_AKM_SUITES) {
- qdf_mem_copy(akmsuite, akmlist,
- sizeof(uint32_t) * akmsuiteCount);
+ memcpy(akmsuite, akmlist, akmsuiteCount);
} else {
hdd_err("Invalid akmSuite count: %u",
akmsuiteCount);
@@ -17922,6 +18001,15 @@
eLen + 2);
if (status)
return status;
+ } else if (genie[0] ==
+ SIR_DH_PARAMETER_ELEMENT_EXT_EID) {
+ hdd_debug("Set DH EXT IE(len %d)",
+ eLen + 2);
+ status = wlan_hdd_add_assoc_ie(
+ pWextState, genie - 2,
+ eLen + 2);
+ if (status)
+ return status;
} else {
hdd_err("UNKNOWN EID: %X", genie[0]);
}
@@ -19928,6 +20016,8 @@
sme_set_del_pmkid_cache(halHandle, pAdapter->sessionId,
&pmk_cache, true);
+ qdf_mem_zero(&pmk_cache, sizeof(pmk_cache));
+
EXIT();
return QDF_IS_STATUS_SUCCESS(result) ? 0 : -EINVAL;
}
@@ -20018,6 +20108,8 @@
sme_set_del_pmkid_cache(halHandle, pAdapter->sessionId, &pmk_cache,
false);
+ qdf_mem_zero(&pmk_cache, sizeof(pmk_cache));
+
EXIT();
return status;
}
@@ -21252,6 +21344,68 @@
}
#endif
+#if defined(WLAN_FEATURE_SAE) && \
+ defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
+/**
+ * __wlan_hdd_cfg80211_external_auth() - Handle external auth
+ * @wiphy: Pointer to wireless phy
+ * @dev: net device
+ * @params: Pointer to external auth params
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_external_auth_params *params)
+{
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+ int ret;
+
+ if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+ hdd_err("Command not allowed in FTM mode");
+ return -EPERM;
+ }
+
+ if (wlan_hdd_validate_session_id(adapter->sessionId)) {
+ hdd_err("invalid session id: %d", adapter->sessionId);
+ return -EINVAL;
+ }
+
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (ret)
+ return ret;
+
+ hdd_debug("external_auth status: %d", params->status);
+ sme_handle_sae_msg(hdd_ctx->hHal, adapter->sessionId, params->status);
+
+ return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_external_auth() - Handle external auth
+ * @wiphy: Pointer to wireless phy
+ * @dev: net device
+ * @params: Pointer to external auth params
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_external_auth_params *params)
+{
+ int ret;
+
+ cds_ssr_protect(__func__);
+ ret = __wlan_hdd_cfg80211_external_auth(wiphy, dev, params);
+ cds_ssr_unprotect(__func__);
+
+ return ret;
+}
+#endif
+
/**
* wlan_hdd_chan_info_cb() - channel info callback
* @chan_info: struct scan_chan_info
@@ -21511,4 +21665,8 @@
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)))
.update_connect_params = wlan_hdd_cfg80211_update_connect_params,
#endif
+#if defined(WLAN_FEATURE_SAE) && \
+ defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
+ .external_auth = wlan_hdd_cfg80211_external_auth,
+#endif
};
diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h
index e77294d..504998b 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.h
+++ b/core/hdd/src/wlan_hdd_cfg80211.h
@@ -144,6 +144,20 @@
#define WLAN_AKM_SUITE_FT_FILS_SHA384 0x000FAC11
#endif
+#ifndef WLAN_AKM_SUITE_OWE
+#define WLAN_AKM_SUITE_OWE 0x000FAC12
+#endif
+
+#define WLAN_AKM_SUITE_EAP_SHA256 0x000FAC0B
+#define WLAN_AKM_SUITE_EAP_SHA384 0x000FAC0C
+
+#ifndef WLAN_AKM_SUITE_SAE
+#define WLAN_AKM_SUITE_SAE 0x000FAC08
+#endif
+
+#ifndef WLAN_AKM_SUITE_DPP_RSN
+#define WLAN_AKM_SUITE_DPP_RSN 0x506F9A02
+#endif
#ifdef FEATURE_WLAN_TDLS
#define WLAN_IS_TDLS_SETUP_ACTION(action) \
@@ -253,6 +267,7 @@
/* Support Tx Power Limit setting */
#define WIFI_FEATURE_SET_TX_POWER_LIMIT 0x4000000
+#define WIFI_FEATURE_P2P_RAND_MAC 0x80000000 /* Support P2P MAC randomization */
/**
* typedef struct sHddAvoidFreqRange - avoid frequency range
diff --git a/core/hdd/src/wlan_hdd_ext_scan.c b/core/hdd/src/wlan_hdd_ext_scan.c
index 10adfe4..d7811a8 100644
--- a/core/hdd/src/wlan_hdd_ext_scan.c
+++ b/core/hdd/src/wlan_hdd_ext_scan.c
@@ -736,9 +736,7 @@
for (j = 0; j < ap_info->numOfRssi; j++)
hdd_debug("Rssi %d", *rssi++);
- ap_info = (tSirWifiSignificantChange *)((char *)ap_info +
- ap_info->numOfRssi * sizeof(*rssi) +
- sizeof(*ap_info));
+ ap_info += ap_info->numOfRssi * sizeof(*rssi);
}
if (nla_put_u32(skb,
@@ -784,9 +782,7 @@
nla_nest_end(skb, ap);
- ap_info = (tSirWifiSignificantChange *)((char *)ap_info
- + ap_info->numOfRssi * sizeof(*rssi) +
- sizeof(*ap_info));
+ ap_info += ap_info->numOfRssi * sizeof(*rssi);
}
nla_nest_end(skb, aps);
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index e25a170..5730572 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -404,10 +404,6 @@
hdd_stop_adapter(hdd_ctx, adapter, true);
clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
-
- if (!hdd_is_cli_iface_up(hdd_ctx))
- sme_scan_flush_result(hdd_ctx->hHal);
-
/* Stop all tx queues */
hdd_info("Disabling queues");
wlan_hdd_netif_queue_control(adapter,
@@ -591,6 +587,7 @@
hdd_info("Changing MAC to " MAC_ADDRESS_STR " of interface %s ",
MAC_ADDR_ARRAY(mac_addr.bytes),
dev->name);
+ memcpy(&adapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
EXIT();
return 0;
@@ -8192,10 +8189,8 @@
pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
if (pIe) {
- /* To acess pIe[15], length needs to be atlest 14 */
- if (pIe[1] < 14) {
- hdd_err("**Wps Ie Length(%hhu) is too small***",
- pIe[1]);
+ if (pIe[1] < (2 + WPS_OUI_TYPE_SIZE)) {
+ hdd_err("**Wps Ie Length is too small***");
ret = -EINVAL;
goto error;
} else if (memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) ==
@@ -8425,6 +8420,12 @@
if (pIe != NULL) {
pIe++;
+ if (pIe[0] > SIR_MAC_RATESET_EID_MAX) {
+ hdd_err("Invalid supported rates %d",
+ pIe[0]);
+ ret = -EINVAL;
+ goto error;
+ }
pConfig->supported_rates.numRates = pIe[0];
pIe++;
for (i = 0;
@@ -8441,6 +8442,12 @@
WLAN_EID_EXT_SUPP_RATES);
if (pIe != NULL) {
pIe++;
+ if (pIe[0] > SIR_MAC_RATESET_EID_MAX) {
+ hdd_err("Invalid supported rates %d",
+ pIe[0]);
+ ret = -EINVAL;
+ goto error;
+ }
pConfig->extended_rates.numRates = pIe[0];
pIe++;
for (i = 0; i < pConfig->extended_rates.numRates; i++) {
diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c
index e2dd267..bf521ae 100644
--- a/core/hdd/src/wlan_hdd_ioctl.c
+++ b/core/hdd/src/wlan_hdd_ioctl.c
@@ -6964,10 +6964,10 @@
{"GETANTENNAMODE", drv_cmd_get_antenna_mode, false},
/* Deprecated commands */
{"STOP", drv_cmd_dummy, false},
- {"RXFILTER-START", drv_cmd_dummy, false},
- {"RXFILTER-STOP", drv_cmd_dummy, false},
- {"BTCOEXSCAN-START", drv_cmd_dummy, false},
- {"BTCOEXSCAN-STOP", drv_cmd_dummy, false},
+ {"RXFILTER-START", drv_cmd_dummy, false},
+ {"RXFILTER-STOP", drv_cmd_dummy, false},
+ {"BTCOEXSCAN-START", drv_cmd_dummy, false},
+ {"BTCOEXSCAN-STOP", drv_cmd_dummy, false},
};
/**
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index aba4e1d..b9f2b07 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -2537,13 +2537,6 @@
clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
/*
- * Upon wifi turn off, DUT has to flush the scan results so if
- * this is the last cli iface, flush the scan database.
- */
- if (!hdd_is_cli_iface_up(hdd_ctx))
- sme_scan_flush_result(hdd_ctx->hHal);
-
- /*
* Find if any iface is up. If any iface is up then can't put device to
* sleep/power save mode
*/
@@ -4693,6 +4686,12 @@
wlan_hdd_tdls_exit(adapter);
wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
hdd_clear_fils_connection_info(adapter);
+ qdf_ret_status = sme_roam_del_pmkid_from_cache(
+ hdd_ctx->hHal,
+ adapter->sessionId,
+ NULL, true);
+ if (QDF_IS_STATUS_ERROR(qdf_ret_status))
+ hdd_err("Cannot flush PMKIDCache");
#ifdef WLAN_OPEN_SOURCE
cancel_work_sync(&adapter->ipv4NotifierWorkQueue);
@@ -8315,6 +8314,8 @@
hdd_adapter_t *adapter = NULL;
void *cds_context = NULL;
int i;
+ struct ieee80211_mgmt *mgmt =
+ (struct ieee80211_mgmt *)frame_ind->frameBuf;
/* Get the global VOSS context.*/
cds_context = cds_get_global_context();
@@ -8328,6 +8329,11 @@
if (0 != wlan_hdd_validate_context(hdd_ctx))
return;
+ if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) {
+ hdd_err(" Invalid frame length");
+ return;
+ }
+
if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
adapter =
@@ -13208,28 +13214,6 @@
QDF_BUG(0);
}
-bool hdd_is_cli_iface_up(hdd_context_t *hdd_ctx)
-{
- hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
- hdd_adapter_t *adapter;
- QDF_STATUS status;
-
- status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
- while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
- adapter = adapter_node->pAdapter;
- if ((adapter->device_mode == QDF_STA_MODE ||
- adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
- qdf_atomic_test_bit(DEVICE_IFACE_OPENED,
- &adapter->event_flags)){
- return true;
- }
- status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
- adapter_node = next;
- }
-
- return false;
-}
-
/* Register the module init/exit functions */
module_init(hdd_module_init);
module_exit(hdd_module_exit);
diff --git a/core/hdd/src/wlan_hdd_ocb.c b/core/hdd/src/wlan_hdd_ocb.c
index 3cc5570..cf46c11 100644
--- a/core/hdd/src/wlan_hdd_ocb.c
+++ b/core/hdd/src/wlan_hdd_ocb.c
@@ -1663,6 +1663,12 @@
request_array = nla_data(
tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_REQUEST_ARRAY]);
+ /* Check channel count. Per 11p spec, max 2 channels allowed */
+ if (!channel_count || channel_count > TGT_NUM_OCB_CHANNELS) {
+ hdd_err("Invalid channel_count %d", channel_count);
+ return -EINVAL;
+ }
+
hdd_request = hdd_request_alloc(¶ms);
if (!hdd_request) {
hdd_err("Request allocation failure");
diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c
index 62f9500..9cdfd01 100644
--- a/core/hdd/src/wlan_hdd_p2p.c
+++ b/core/hdd/src/wlan_hdd_p2p.c
@@ -1958,6 +1958,7 @@
bool enb_random_mac = false;
uint32_t mgmt_hdr_len = sizeof(struct ieee80211_hdr_3addr);
int32_t mgmt_id;
+ QDF_STATUS qdf_status;
ENTER();
@@ -1991,6 +1992,22 @@
hdd_device_mode_to_string(pAdapter->device_mode),
pAdapter->device_mode, type, wait, offchan);
+ /*
+ * When frame to be transmitted is auth mgmt, then trigger
+ * sme_send_mgmt_tx to send auth frame
+ */
+ if ((pAdapter->device_mode == QDF_STA_MODE) &&
+ (type == SIR_MAC_MGMT_FRAME &&
+ subType == SIR_MAC_MGMT_AUTH)) {
+ qdf_status = sme_send_mgmt_tx(WLAN_HDD_GET_HAL_CTX(pAdapter),
+ pAdapter->sessionId, buf, len);
+
+ if (QDF_IS_STATUS_SUCCESS(qdf_status))
+ return 0;
+ else
+ return -EINVAL;
+ }
+
if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_ACTION &&
len > IEEE80211_MIN_ACTION_SIZE)
hdd_debug("category: %d, actionId: %d",
diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c
index 17fca19..dd8e313 100644
--- a/core/hdd/src/wlan_hdd_scan.c
+++ b/core/hdd/src/wlan_hdd_scan.c
@@ -813,9 +813,6 @@
* wlan_hdd_scan_request_enqueue() - enqueue Scan Request
* @adapter: Pointer to the adapter
* @scan_req: Pointer to the scan request
- * @source: source of scan request either vendor or nl
- * @scan_id: scan id from wma
- * @timestamp: timestamp value
*
* Enqueue scan request in the global HDD scan list.This list
* stores the active scan request information.
@@ -1152,7 +1149,7 @@
}
hdd_update_dbs_scan_ctrl_ext_flag(hdd_ctx, &scanRequest);
scanRequest.timestamp = qdf_mc_timer_get_system_time();
- sme_get_scan_id(&scanRequest.scan_id);
+ wma_get_scan_id(&scanRequest.scan_id);
pAdapter->scan_info.mScanPending = true;
wlan_hdd_scan_request_enqueue(pAdapter, NULL, NL_SCAN,
scanRequest.scan_id,
@@ -1311,10 +1308,9 @@
/**
* hdd_vendor_scan_callback() - Scan completed callback event
- * @adapter: pointer to adapter
- * @req: Scan request
- * @aborted: true scan aborted false scan success
- * @scan_id: Scan request unique identifier
+ * @hddctx: HDD context
+ * @req : Scan request
+ * @aborted : true scan aborted false scan success
*
* This function sends scan completed callback event to NL.
*
@@ -1322,14 +1318,14 @@
*/
static void hdd_vendor_scan_callback(hdd_adapter_t *adapter,
struct cfg80211_scan_request *req,
- bool aborted, uint32_t scan_id)
+ bool aborted)
{
- hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ hdd_context_t *hddctx = WLAN_HDD_GET_CTX(adapter);
struct sk_buff *skb;
struct nlattr *attr;
int i;
uint8_t scan_status;
- u64 cookie = scan_id;
+ uint64_t cookie;
ENTER();
@@ -1338,10 +1334,7 @@
qdf_mem_free(req);
return;
}
-
- hdd_debug("vendor scan id: %x", scan_id);
-
- skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, &(adapter->wdev),
+ skb = cfg80211_vendor_event_alloc(hddctx->wiphy, &(adapter->wdev),
SCAN_DONE_EVENT_BUF_SIZE + 4 + NLMSG_HDRLEN,
QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX,
GFP_KERNEL);
@@ -1352,6 +1345,7 @@
return;
}
+ cookie = (uintptr_t)req;
attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS);
if (!attr)
goto nla_put_failure;
@@ -1386,8 +1380,8 @@
goto nla_put_failure;
}
if (hdd_wlan_nla_put_u64(skb,
- QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE,
- cookie)) {
+ QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE,
+ cookie)) {
hdd_err("Failed to add scan cookie");
goto nla_put_failure;
}
@@ -1563,7 +1557,7 @@
if (NL_SCAN == source)
hdd_cfg80211_scan_done(pAdapter, req, aborted);
else
- hdd_vendor_scan_callback(pAdapter, req, aborted, scanId);
+ hdd_vendor_scan_callback(pAdapter, req, aborted);
allow_suspend:
qdf_runtime_pm_allow_suspend(&hddctx->runtime_context.scan);
@@ -1684,8 +1678,7 @@
hdd_cfg80211_scan_done(adapter, request, true);
} else {
hdd_err("Vendor scan aborted. Null result sent");
- hdd_vendor_scan_callback(adapter, request, true,
- blocked_scan_req->scan_id);
+ hdd_vendor_scan_callback(adapter, request, true);
}
qdf_mem_free(blocked_scan_req);
}
@@ -1959,7 +1952,7 @@
static int
wlan_hdd_enqueue_blocked_scan_request(struct net_device *dev,
struct cfg80211_scan_request *request,
- uint8_t source, uint32_t scan_id)
+ uint8_t source)
{
hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
struct hdd_scan_req *blocked_scan_req =
@@ -1974,7 +1967,7 @@
blocked_scan_req->adapter = adapter;
blocked_scan_req->scan_request = request;
blocked_scan_req->source = source;
- blocked_scan_req->scan_id = scan_id;
+ blocked_scan_req->scan_id = 0;
qdf_mutex_acquire(&adapter->blocked_scan_request_q_lock);
if (qdf_list_size(&adapter->blocked_scan_request_q) <
@@ -2002,7 +1995,6 @@
* @dev: Pointer to net device
* @request: Pointer to scan request
* @source: scan request source(NL/Vendor scan)
- * @scan_id: output pointer to hold scan_id
*
* This API responds to scan trigger and update cfg80211 scan database
* later, scan dump command can be used to recieve scan results
@@ -2011,7 +2003,7 @@
*/
static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
struct cfg80211_scan_request *request,
- uint8_t source, uint32_t *scan_id)
+ uint8_t source)
{
struct net_device *dev = request->wdev->netdev;
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
@@ -2061,14 +2053,8 @@
conn_info.connState) &&
(!pHddCtx->config->enable_connected_scan)) {
hdd_info("enable_connected_scan is false, Aborting scan");
- sme_get_scan_id(&scan_req_id);
- if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source,
- scan_req_id))
+ if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source))
return -EAGAIN;
-
- if (scan_id)
- *scan_id = scan_req_id;
-
schedule_work(&pAdapter->scan_block_work);
return 0;
}
@@ -2125,15 +2111,9 @@
* startup.
*/
hdd_err("##In DFS Master mode. Scan aborted");
- sme_get_scan_id(&scan_req_id);
if (wlan_hdd_enqueue_blocked_scan_request(dev, request,
- source,
- scan_req_id))
+ source))
return -EAGAIN;
-
- if (scan_id)
- *scan_id = scan_req_id;
-
schedule_work(&pAdapter->scan_block_work);
return 0;
}
@@ -2234,14 +2214,8 @@
if (pAdapter->device_mode == QDF_SAP_MODE &&
wlan_hdd_sap_skip_scan_check(pHddCtx, request)) {
hdd_debug("sap scan skipped");
- sme_get_scan_id(&scan_req_id);
- if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source,
- scan_req_id))
+ if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source))
return -EAGAIN;
-
- if (scan_id)
- *scan_id = scan_req_id;
-
schedule_work(&pAdapter->scan_block_work);
return 0;
}
@@ -2382,12 +2356,6 @@
pAdapter->sessionId);
}
if (request->ie_len) {
- if (request->ie_len > SIR_MAC_MAX_ADD_IE_LENGTH) {
- hdd_debug("Invalid ie_len: %zu", request->ie_len);
- status = -EINVAL;
- goto free_mem;
- }
-
/* save this for future association (join requires this) */
memset(&pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE));
memcpy(pScanInfo->scanAddIE.addIEdata, request->ie,
@@ -2506,19 +2474,10 @@
hdd_update_scan_flags(&scan_req, request);
hdd_update_dbs_scan_ctrl_ext_flag(pHddCtx, &scan_req);
qdf_runtime_pm_prevent_suspend(&pHddCtx->runtime_context.scan);
- sme_get_scan_id(&scan_req_id);
+ wma_get_scan_id(&scan_req_id);
scan_req.scan_id = scan_req_id;
- status = wlan_hdd_scan_request_enqueue(pAdapter, request, source,
+ wlan_hdd_scan_request_enqueue(pAdapter, request, source,
scan_req.scan_id, scan_req.timestamp);
- if (status) {
- qdf_runtime_pm_allow_suspend(&pHddCtx->runtime_context.scan);
- hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
- goto free_mem;
- }
-
- if (scan_id)
- *scan_id = scan_req_id;
-
pAdapter->scan_info.mScanPending = true;
status = sme_scan_request(WLAN_HDD_GET_HAL_CTX(pAdapter),
pAdapter->sessionId, &scan_req,
@@ -2582,7 +2541,7 @@
cds_ssr_protect(__func__);
ret = __wlan_hdd_cfg80211_scan(wiphy,
- request, NL_SCAN, NULL);
+ request, NL_SCAN);
cds_ssr_unprotect(__func__);
return ret;
}
@@ -2607,7 +2566,7 @@
cds_ssr_protect(__func__);
ret = __wlan_hdd_cfg80211_scan(wiphy,
- request, source, NULL);
+ request, source);
cds_ssr_unprotect(__func__);
return ret;
}
@@ -2649,16 +2608,15 @@
* wlan_hdd_send_scan_start_event() -API to send the scan start event
* @wiphy: Pointer to wiphy
* @wdev: Pointer to net device
- * @scan_id: scan identifier
+ * @cookie: scan identifier
*
* Return: return 0 on success and negative error code on failure
*/
static int wlan_hdd_send_scan_start_event(struct wiphy *wiphy,
- struct wireless_dev *wdev, uint32_t scan_id)
+ struct wireless_dev *wdev, uint64_t cookie)
{
struct sk_buff *skb;
int ret;
- u64 cookie = scan_id;
skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u64) +
NLA_HDRLEN + NLMSG_HDRLEN);
@@ -2817,7 +2775,6 @@
struct ieee80211_channel *chan;
hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
int ret;
- uint32_t scan_id = 0;
ENTER_DEV(wdev->netdev);
@@ -2987,16 +2944,14 @@
request->wiphy = wiphy;
request->scan_start = jiffies;
- ret = __wlan_hdd_cfg80211_scan(wiphy, request, VENDOR_SCAN, &scan_id);
+ ret = __wlan_hdd_cfg80211_scan(wiphy, request, VENDOR_SCAN);
if (0 != ret) {
hdd_err_ratelimited(HDD_SCAN_REJECT_RATE_LIMIT,
"Scan Failed. Ret = %d", ret);
qdf_mem_free(request);
return ret;
}
- hdd_debug("vendor scan id: %x", scan_id);
-
- ret = wlan_hdd_send_scan_start_event(wiphy, wdev, scan_id);
+ ret = wlan_hdd_send_scan_start_event(wiphy, wdev, (uintptr_t)request);
return ret;
error:
@@ -3030,17 +2985,19 @@
return ret;
}
/**
- * wlan_hdd_validate_scan_id() - API to validate scan id obtained from cookie
+ * wlan_hdd_get_scanid() - API to get the scan id
+ * from the scan cookie attribute.
* @hdd_ctx: Pointer to HDD context
- * @scan_id: scan identifier
+ * @scan_id: Pointer to scan id
+ * @cookie : Scan cookie attribute
*
- * API to validate scan id obtained from from cookie attribute
- * sent from supplicant.
+ * API to get the scan id from the scan cookie attribute
+ * sent from supplicant by matching scan request.
*
* Return: 0 for success, non zero for failure
*/
-static int
-wlan_hdd_validate_scan_id(hdd_context_t *hdd_ctx, uint32_t scan_id)
+static int wlan_hdd_get_scanid(hdd_context_t *hdd_ctx,
+ uint32_t *scan_id, uint64_t cookie)
{
struct hdd_scan_req *scan_req;
qdf_list_node_t *node = NULL;
@@ -3064,8 +3021,9 @@
node = ptr_node;
scan_req = container_of(node, struct hdd_scan_req, node);
- if (scan_id == scan_req->scan_id) {
- hdd_debug("scan id: %x found", scan_id);
+ if (cookie ==
+ (uintptr_t)(scan_req->scan_request)) {
+ *scan_id = scan_req->scan_id;
ret = 0;
break;
}
@@ -3096,7 +3054,7 @@
{
hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
- uint32_t scan_id;
+ uint32_t scan_id = 0;
uint64_t cookie;
int ret;
@@ -3120,8 +3078,7 @@
return -EINVAL;
cookie = nla_get_u64(tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
- scan_id = (uint32_t)cookie;
- ret = wlan_hdd_validate_scan_id(hdd_ctx, scan_id);
+ ret = wlan_hdd_get_scanid(hdd_ctx, &scan_id, cookie);
if (ret)
return ret;
@@ -3917,7 +3874,6 @@
bool aborted = true;
QDF_STATUS status;
hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter_node = NULL;
- uint32_t scan_id;
if (NULL == hdd_ctx) {
hdd_err("HDD context is Null");
@@ -3946,7 +3902,6 @@
req = hdd_scan_req->scan_request;
source = hdd_scan_req->source;
adapter = hdd_scan_req->adapter;
- scan_id = hdd_scan_req->scan_id;
if (!padapter || (padapter == adapter)) {
@@ -3976,10 +3931,9 @@
req, aborted);
else
hdd_vendor_scan_callback(adapter,
- req, aborted,
- scan_id);
+ req, aborted);
hdd_debug("removed Scan id: %d, req = %pK",
- scan_id, req);
+ hdd_scan_req->scan_id, req);
}
qdf_mem_free(hdd_scan_req);
qdf_spin_lock(&hdd_ctx->hdd_scan_req_q_lock);
diff --git a/core/hdd/src/wlan_hdd_spectral.c b/core/hdd/src/wlan_hdd_spectral.c
index 23cb9e4..7b6735d 100644
--- a/core/hdd/src/wlan_hdd_spectral.c
+++ b/core/hdd/src/wlan_hdd_spectral.c
@@ -115,10 +115,7 @@
return -EPERM;
}
adapter = WLAN_HDD_GET_PRIV_PTR(dev);
- if (wlan_hdd_validate_session_id(adapter->sessionId)) {
- hdd_err("invalid session id: %d", adapter->sessionId);
- return -EINVAL;
- }
+
/* initialize config parameters*/
config_req = hdd_ctx->ss_config;
diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c
index 698124f..8a451d8 100644
--- a/core/hdd/src/wlan_hdd_wext.c
+++ b/core/hdd/src/wlan_hdd_wext.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -3435,6 +3435,7 @@
case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
#endif
+ case eCSR_AUTH_TYPE_DPP_RSN:
rsnType = true;
break;
/* case eCSR_AUTH_TYPE_FAILED: */
@@ -4050,6 +4051,9 @@
qdf_mem_zero(pWextState->roamProfile.Keys.KeyLength, CSR_MAX_NUM_KEY);
+ qdf_mem_zero(pWextState->roamProfile.Keys.KeyMaterial,
+ sizeof(pWextState->roamProfile.Keys.KeyMaterial));
+
#ifdef FEATURE_WLAN_WAPI
pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_OPEN;
pAdapter->wapi_info.nWapiMode = 0;
@@ -4401,8 +4405,8 @@
* Return: 0 on success, error number otherwise
*/
static int iw_get_name(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
int ret;
diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h
index 571e6c3..bb6d1d1 100644
--- a/core/mac/inc/ani_global.h
+++ b/core/mac/inc/ani_global.h
@@ -334,6 +334,9 @@
TX_TIMER gLimActiveToPassiveChannelTimer;
TX_TIMER g_lim_periodic_auth_retry_timer;
+ /* SAE authentication related timer */
+ TX_TIMER sae_auth_timer;
+
/* ********************TIMER SECTION ENDS************************************************** */
/* ALL THE FIELDS BELOW THIS CAN BE ZEROED OUT in lim_initialize */
/* **************************************************************************************** */
diff --git a/core/mac/inc/ani_system_defs.h b/core/mac/inc/ani_system_defs.h
index 99fd5ee..ac5f65c 100644
--- a/core/mac/inc/ani_system_defs.h
+++ b/core/mac/inc/ani_system_defs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -68,13 +68,14 @@
eSIR_OPEN_SYSTEM,
eSIR_SHARED_KEY,
eSIR_FT_AUTH,
+ eSIR_AUTH_TYPE_SAE = 3,
#if defined FEATURE_WLAN_ESE
eSIR_LEAP_AUTH = 0x80,
#endif
- eSIR_AUTO_SWITCH,
eSIR_FILS_SK_WITHOUT_PFS = 4,
eSIR_FILS_SK_WITH_PFS = 5,
eSIR_FILS_PK_AUTH = 6,
+ eSIR_AUTO_SWITCH,
eSIR_DONOT_USE_AUTH_TYPE = SIR_MAX_ENUM_SIZE
} tAniAuthType;
@@ -95,6 +96,8 @@
/* Firmware uses key length to find GCMP 128 or 256 */
eSIR_ED_GCMP,
eSIR_ED_GCMP_256,
+ eSIR_ED_AES_GMAC_128,
+ eSIR_ED_AES_GMAC_256,
eSIR_ED_NOT_IMPLEMENTED = SIR_MAX_ENUM_SIZE
} tAniEdType;
diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h
index 627ad8f..7cfc7cc 100644
--- a/core/mac/inc/qwlan_version.h
+++ b/core/mac/inc/qwlan_version.h
@@ -38,12 +38,12 @@
===========================================================================*/
-#define QWLAN_VERSION_MAJOR 5
-#define QWLAN_VERSION_MINOR 3
-#define QWLAN_VERSION_PATCH 1
-#define QWLAN_VERSION_EXTRA "T"
-#define QWLAN_VERSION_BUILD 1
+#define QWLAN_VERSION_MAJOR 6
+#define QWLAN_VERSION_MINOR 0
+#define QWLAN_VERSION_PATCH 0
+#define QWLAN_VERSION_EXTRA "A"
+#define QWLAN_VERSION_BUILD 0
-#define QWLAN_VERSIONSTR "5.3.1.1T.2"
+#define QWLAN_VERSIONSTR "6.0.0.0A"
#endif /* QWLAN_VERSION_H */
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index a4e1d71..28fc41f 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -1330,6 +1330,7 @@
#ifdef WLAN_FEATURE_FILS_SK
struct cds_fils_connection_info fils_con_info;
#endif
+ bool sae_pmk_cached;
bool ignore_assoc_disallowed;
bool enable_bcast_probe_rsp;
bool force_24ghz_in_ht20;
@@ -8468,7 +8469,7 @@
};
typedef void (*roam_scan_stats_cb)(void *context,
- struct wmi_roam_scan_stats_res *res);
+ struct wmi_roam_scan_stats_res *res);
/**
* struct sir_roam_scan_stats - Stores roam scan context
@@ -8481,5 +8482,34 @@
roam_scan_stats_cb cb;
void *context;
};
+/**
+ * struct sae_info - SAE info used for commit/confirm messages
+ * @msg_type: Message type
+ * @msg_len: length of message
+ * @vdev_id: vdev id
+ * @peer_mac_addr: peer MAC address
+ * @ssid: SSID
+ */
+struct sir_sae_info {
+ uint16_t msg_type;
+ uint16_t msg_len;
+ uint32_t vdev_id;
+ struct qdf_mac_addr peer_mac_addr;
+ tSirMacSSid ssid;
+};
+
+/**
+ * struct sir_sae_msg - SAE msg used for message posting
+ * @message_type: message type
+ * @length: message length
+ * @session_id: SME session id
+ * @sae_status: SAE status, 0: Success, Non-zero: Failure.
+ */
+struct sir_sae_msg {
+ uint16_t message_type;
+ uint16_t length;
+ uint16_t session_id;
+ uint8_t sae_status;
+};
#endif /* __SIR_API_H */
diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h
index ddc7bc2..7f982ff 100644
--- a/core/mac/inc/sir_mac_prot_def.h
+++ b/core/mac/inc/sir_mac_prot_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -448,6 +448,9 @@
#define SIR_MAC_OUI_VERSION_1 1
+/* OWE DH Parameter element https://tools.ietf.org/html/rfc8110 */
+#define SIR_DH_PARAMETER_ELEMENT_EXT_EID 32
+
/* OUI and type definition for WPA IE in network byte order */
#define SIR_MAC_WPA_OUI 0x01F25000
#define SIR_MAC_WME_OUI 0x02F25000
diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h
index 784513c..b0da058 100644
--- a/core/mac/inc/wni_api.h
+++ b/core/mac/inc/wni_api.h
@@ -274,6 +274,9 @@
eWNI_SME_RX_AGGR_HOLE_IND,
eWNI_SME_TDLS_NOTIFY_SET_STATE_DISABLE,
eWNI_SME_UPDATE_CONFIG,
+ eWNI_SME_TRIGGER_SAE,
+ eWNI_SME_SEND_MGMT_FRAME_TX,
+ eWNI_SME_SEND_SAE_MSG,
eWNI_SME_MSG_TYPES_END
};
diff --git a/core/mac/src/cfg/cfgUtil/dot11f.frms b/core/mac/src/cfg/cfgUtil/dot11f.frms
index 87dd01d..3dddb39 100644
--- a/core/mac/src/cfg/cfgUtil/dot11f.frms
+++ b/core/mac/src/cfg/cfgUtil/dot11f.frms
@@ -2622,6 +2622,12 @@
data[0..255];
}
+IE dh_parameter_element (EID_EXTN_ID_ELEMENT) OUI ( 0x20 )
+{
+ group[2];
+ public_key[0..255];
+}
+
const EID_RRM_BEACON_REPORTING = 1;
const EID_RRM_BCN_REPORTING_DETAIL = 2;
@@ -3371,6 +3377,7 @@
OPTIE fils_key_confirmation;
OPTIE fils_hlp_container;
OPTIE fragment_ie;
+ OPTIE dh_parameter_element;
OPTIE WPAOpaque;
OPTIE WMMCaps;
OPTIE WMMInfoStation;
diff --git a/core/mac/src/include/dot11f.h b/core/mac/src/include/dot11f.h
index 2000156..ef3a88c 100644
--- a/core/mac/src/include/dot11f.h
+++ b/core/mac/src/include/dot11f.h
@@ -8071,6 +8071,47 @@
}; /* End extern "C". */
#endif /* C++ */
+/* EID 255 (0xff) Extended EID 32 (0x20) */
+typedef struct sDot11fIEdh_parameter_element {
+ uint8_t present;
+ uint8_t group[2];
+ uint8_t num_public_key;
+ uint8_t public_key[255];
+} tDot11fIEdh_parameter_element;
+
+#define DOT11F_EID_DH_PARAMETER_ELEMENT (255)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_DH_PARAMETER_ELEMENT_MIN_LEN (2)
+
+#define DOT11F_IE_DH_PARAMETER_ELEMENT_MAX_LEN (257)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+__must_check uint32_t dot11f_unpack_ie_dh_parameter_element(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEdh_parameter_element*,
+ bool);
+
+uint32_t dot11f_pack_ie_dh_parameter_element(
+ tpAniSirGlobal,
+ tDot11fIEdh_parameter_element *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_dh_parameter_element(
+ tpAniSirGlobal,
+ tDot11fIEdh_parameter_element *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
/* EID 60 (0x3c) */
typedef struct sDot11fIEext_chan_switch_ann {
uint8_t present;
@@ -8881,6 +8922,7 @@
tDot11fIEfils_key_confirmation fils_key_confirmation;
tDot11fIEfils_hlp_container fils_hlp_container;
tDot11fIEfragment_ie fragment_ie;
+ tDot11fIEdh_parameter_element dh_parameter_element;
tDot11fIEWPAOpaque WPAOpaque;
tDot11fIEWMMCaps WMMCaps;
tDot11fIEWMMInfoStation WMMInfoStation;
diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h
index 6de1565..6e9bd71 100644
--- a/core/mac/src/include/sir_params.h
+++ b/core/mac/src/include/sir_params.h
@@ -203,6 +203,20 @@
uint32_t data[1];
} tSirMbMsgP2p, *tpSirMbMsgP2p;
+/**
+ * struct sir_mgmt_msg - Structure used to send auth frame from CSR to LIM
+ * @type: Message type
+ * @msg_len: Message length
+ * @session_id: session id
+ * @data: Pointer to data tobe transmitted
+ */
+struct sir_mgmt_msg {
+ uint16_t type;
+ uint16_t msg_len;
+ uint8_t session_id;
+ uint8_t *data;
+};
+
/* ******************************************* *
* *
* SIRIUS MESSAGE TYPES *
@@ -782,6 +796,8 @@
(SIR_LIM_TIMEOUT_MSG_START + 0x2C)
#define SIR_LIM_AUTH_RETRY_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x2D)
+#define SIR_LIM_AUTH_SAE_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x2E)
+
#define SIR_LIM_MSG_TYPES_END (SIR_LIM_MSG_TYPES_BEGIN+0xFF)
/* SCH message types */
diff --git a/core/mac/src/pe/include/lim_global.h b/core/mac/src/pe/include/lim_global.h
index 7e8a74d..a5c12a2 100644
--- a/core/mac/src/pe/include/lim_global.h
+++ b/core/mac/src/pe/include/lim_global.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -166,6 +166,7 @@
eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE,
eLIM_MLM_WT_FT_REASSOC_RSP_STATE,
eLIM_MLM_P2P_LISTEN_STATE,
+ eLIM_MLM_WT_SAE_AUTH_STATE,
} tLimMlmStates;
/* 11h channel quiet states */
diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h
index 6a1c992..a8e8ca7 100644
--- a/core/mac/src/pe/include/lim_session.h
+++ b/core/mac/src/pe/include/lim_session.h
@@ -513,6 +513,7 @@
bool recvd_disassoc_while_roaming;
bool deauth_disassoc_rc;
int8_t def_max_tx_pwr;
+ bool sae_pmk_cached;
} tPESession, *tpPESession;
/*-------------------------------------------------------------------------
diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c
index f0cc82b..5a7f43c 100644
--- a/core/mac/src/pe/lim/lim_api.c
+++ b/core/mac/src/pe/lim/lim_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -615,6 +615,8 @@
}
if (pMac->lim.gpLimMlmSetKeysReq != NULL) {
+ qdf_mem_zero(pMac->lim.gpLimMlmSetKeysReq,
+ sizeof(tLimMlmSetKeysReq));
qdf_mem_free(pMac->lim.gpLimMlmSetKeysReq);
pMac->lim.gpLimMlmSetKeysReq = NULL;
}
diff --git a/core/mac/src/pe/lim/lim_assoc_utils.c b/core/mac/src/pe/lim/lim_assoc_utils.c
index e7ca136..a01d870 100644
--- a/core/mac/src/pe/lim/lim_assoc_utils.c
+++ b/core/mac/src/pe/lim/lim_assoc_utils.c
@@ -349,8 +349,8 @@
* frame handling to determine whether received RSN in
* Assoc/Reassoc request frames include supported cipher suites or not.
*
- * Return: eSIR_SUCCESS if ALL BSS basic rates are present in the
- * received rateset else failure status.
+ * Return: eSIR_SUCCESS if ALL supported cipher suites are present in the
+ * received rsn IE else failure status.
*/
uint8_t
@@ -461,8 +461,8 @@
* frame handling to determine whether received RSN in
* Assoc/Reassoc request frames include supported cipher suites or not.
*
- * Return: Success if ALL BSS basic rates are present in the
- * received rateset else failure status.
+ * Return: Success if ALL supported cipher suites are present in the
+ * received wpa IE else failure status.
*/
uint8_t
diff --git a/core/mac/src/pe/lim/lim_process_action_frame.c b/core/mac/src/pe/lim/lim_process_action_frame.c
index bdaa515..a48dd20 100644
--- a/core/mac/src/pe/lim/lim_process_action_frame.c
+++ b/core/mac/src/pe/lim/lim_process_action_frame.c
@@ -1959,6 +1959,7 @@
break;
case SIR_MAC_ACTION_PUBLIC_USAGE:
mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
switch (action_hdr->actionID) {
case SIR_MAC_ACTION_EXT_CHANNEL_SWITCH_ID:
lim_process_ext_channel_switch_action_frame(mac_ctx,
diff --git a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c
index 316324b..9f8a5d7 100644
--- a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c
+++ b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c
@@ -737,7 +737,7 @@
*
* wpa ie related checks
*
- * Return: true of no error, false otherwise
+ * Return: true if no error, false otherwise
*/
static bool lim_chk_n_process_wpa_rsn_ie(tpAniSirGlobal mac_ctx,
tpSirMacMgmtHdr hdr,
@@ -746,6 +746,7 @@
uint8_t sub_type, bool *pmf_connection)
{
uint8_t *wps_ie = NULL;
+ uint32_t ret;
tDot11fIEWPA dot11f_ie_wpa = {0};
tDot11fIERSN dot11f_ie_rsn = {0};
tSirRetStatus status = eSIR_SUCCESS;
@@ -776,11 +777,11 @@
if (assoc_req->rsnPresent) {
if (assoc_req->rsn.length) {
/* Unpack the RSN IE */
- if (dot11f_unpack_ie_rsn(mac_ctx,
+ ret = dot11f_unpack_ie_rsn(mac_ctx,
&assoc_req->rsn.info[0],
assoc_req->rsn.length,
- &dot11f_ie_rsn, false) !=
- DOT11F_PARSE_SUCCESS) {
+ &dot11f_ie_rsn, false);
+ if (!DOT11F_SUCCEEDED(ret)) {
pe_err("Invalid RSN ie");
return false;
}
@@ -852,11 +853,11 @@
/* Unpack the WPA IE */
if (assoc_req->wpa.length) {
/* OUI is not taken care */
- if (dot11f_unpack_ie_wpa(mac_ctx,
- &assoc_req->wpa.info[4],
- assoc_req->wpa.length,
- &dot11f_ie_wpa, false) !=
- DOT11F_PARSE_SUCCESS) {
+ ret = dot11f_unpack_ie_wpa(mac_ctx,
+ &assoc_req->wpa.info[4],
+ (assoc_req->wpa.length - 4),
+ &dot11f_ie_wpa, false);
+ if (!DOT11F_SUCCEEDED(ret)) {
pe_err("Invalid WPA IE");
return false;
}
@@ -1844,11 +1845,6 @@
if ((session->access_policy_vendor_ie) &&
(session->access_policy ==
LIM_ACCESS_POLICY_RESPOND_IF_IE_IS_PRESENT)) {
- if (frame_len <= LIM_ASSOC_REQ_IE_OFFSET) {
- pe_debug("Received action frame of invalid len %d",
- frame_len);
- return;
- }
if (!cfg_get_vendor_ie_ptr_from_oui(mac_ctx,
&session->access_policy_vendor_ie[2],
3, frm_body + LIM_ASSOC_REQ_IE_OFFSET,
diff --git a/core/mac/src/pe/lim/lim_process_auth_frame.c b/core/mac/src/pe/lim/lim_process_auth_frame.c
index 04258eb..5358567 100644
--- a/core/mac/src/pe/lim/lim_process_auth_frame.c
+++ b/core/mac/src/pe/lim/lim_process_auth_frame.c
@@ -285,6 +285,45 @@
pe_session);
}
+#ifdef WLAN_FEATURE_SAE
+/**
+ * lim_process_sae_auth_frame()-Process SAE authentication frame
+ * @mac_ctx: MAC context
+ * @rx_pkt_info: Rx packet
+ * @pe_session: PE session
+ *
+ * Return: None
+ */
+static void lim_process_sae_auth_frame(tpAniSirGlobal mac_ctx,
+ uint8_t *rx_pkt_info, tpPESession pe_session)
+{
+ tpSirMacMgmtHdr mac_hdr;
+ uint32_t frame_len;
+ uint8_t *body_ptr;
+
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+ pe_debug("Received SAE Auth frame type %d subtype %d",
+ mac_hdr->fc.type, mac_hdr->fc.subType);
+
+ if (pe_session->limMlmState != eLIM_MLM_WT_SAE_AUTH_STATE)
+ pe_err("received SAE auth response in unexpected state %x",
+ pe_session->limMlmState);
+
+ lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType,
+ (uint8_t *) mac_hdr,
+ frame_len + sizeof(tSirMacMgmtHdr), 0,
+ WMA_GET_RX_CH(rx_pkt_info), pe_session,
+ WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info));
+}
+#else
+static inline void lim_process_sae_auth_frame(tpAniSirGlobal mac_ctx,
+ uint8_t *rx_pkt_info, tpPESession pe_session)
+{}
+#endif
+
static void lim_process_auth_frame_type1(tpAniSirGlobal mac_ctx,
tpSirMacMgmtHdr mac_hdr,
tSirMacAuthFrameBody *rx_auth_frm_body,
@@ -611,16 +650,27 @@
if (rx_auth_frm_body->authAlgoNumber !=
mac_ctx->lim.gpLimMlmAuthReq->authType) {
/*
- * Received Authentication frame with an auth
- * algorithm other than one requested.
- * Wait until Authentication Failure Timeout.
+ * Auth algo is open in rx auth frame when auth type is SAE and
+ * PMK is cached as driver sent auth algo as open in tx frame
+ * as well.
*/
+ if ((mac_ctx->lim.gpLimMlmAuthReq->authType ==
+ eSIR_AUTH_TYPE_SAE) && pe_session->sae_pmk_cached) {
+ pe_debug("rx Auth frame2 auth algo %d in SAE PMK case",
+ rx_auth_frm_body->authAlgoNumber);
+ } else {
+ /*
+ * Received Authentication frame with an auth
+ * algorithm other than one requested.
+ * Wait until Authentication Failure Timeout.
+ */
- pe_warn("rx Auth frame2 for unexpected auth algo number %d "
- MAC_ADDRESS_STR,
- rx_auth_frm_body->authAlgoNumber,
- MAC_ADDR_ARRAY(mac_hdr->sa));
- return;
+ pe_warn("rx Auth frame2 for unexpected auth algo %d"
+ MAC_ADDRESS_STR,
+ rx_auth_frm_body->authAlgoNumber,
+ MAC_ADDR_ARRAY(mac_hdr->sa));
+ return;
+ }
}
if (rx_auth_frm_body->authStatusCode != eSIR_MAC_SUCCESS_STATUS) {
@@ -1078,7 +1128,7 @@
uint8_t defaultkey[SIR_MAC_KEY_LENGTH];
uint8_t *plainbody = NULL;
uint8_t decrypt_result;
- uint16_t frame_len, curr_seq_num = 0;
+ uint16_t frame_len, curr_seq_num = 0, auth_alg;
uint32_t val, key_length = 8;
tSirMacAuthFrameBody *rx_auth_frm_body, *rx_auth_frame, *auth_frame;
tpSirMacMgmtHdr mac_hdr;
@@ -1131,6 +1181,9 @@
body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+ auth_alg = *(uint16_t *) body_ptr;
+ pe_debug("auth_alg %d ", auth_alg);
+
if (frame_len < 2) {
pe_err("invalid frame len: %d", frame_len);
return;
@@ -1370,6 +1423,11 @@
pe_err("failed to convert Auth Frame to structure or Auth is not valid");
goto free;
}
+ } else if ((auth_alg ==
+ eSIR_AUTH_TYPE_SAE) && (LIM_IS_STA_ROLE(pe_session))) {
+ lim_process_sae_auth_frame(mac_ctx,
+ rx_pkt_info, pe_session);
+ goto free;
} else if ((sir_convert_auth_frame2_struct(mac_ctx, body_ptr,
frame_len, rx_auth_frame) != eSIR_SUCCESS)
|| (!is_auth_valid(mac_ctx, rx_auth_frame,
diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c
index 151d05b..18b869b 100644
--- a/core/mac/src/pe/lim/lim_process_message_queue.c
+++ b/core/mac/src/pe/lim/lim_process_message_queue.c
@@ -64,11 +64,78 @@
#include "qdf_mem.h"
#include "cds_concurrency.h"
#include "nan_datapath.h"
+#include "lim_security_utils.h"
+#include "cds_ieee80211_common.h"
void lim_log_session_states(tpAniSirGlobal pMac);
static void lim_process_normal_hdd_msg(tpAniSirGlobal mac_ctx,
struct sSirMsgQ *msg, uint8_t rsp_reqd);
+#ifdef WLAN_FEATURE_SAE
+/**
+ * lim_process_sae_msg() - Process SAE message
+ * @mac: Global MAC pointer
+ * @body: Buffer pointer
+ *
+ * Return: None
+ */
+static void lim_process_sae_msg(tpAniSirGlobal mac, struct sir_sae_msg *body)
+{
+ struct sir_sae_msg *sae_msg = body;
+ tpPESession session;
+
+ if (!sae_msg) {
+ pe_err("SAE msg is NULL");
+ return;
+ }
+
+ session = pe_find_session_by_sme_session_id(mac,
+ sae_msg->session_id);
+ if (session == NULL) {
+ pe_err("SAE:Unable to find session");
+ return;
+ }
+
+ if (session->pePersona != QDF_STA_MODE) {
+ pe_err("SAE:Not supported in this mode %d",
+ session->pePersona);
+ return;
+ }
+
+ pe_debug("SAE:status %d limMlmState %d pePersona %d",
+ sae_msg->sae_status, session->limMlmState,
+ session->pePersona);
+ switch (session->limMlmState) {
+ case eLIM_MLM_WT_SAE_AUTH_STATE:
+ /* SAE authentication is completed. Restore from auth state */
+ if (tx_timer_running(&mac->lim.limTimers.sae_auth_timer))
+ lim_deactivate_and_change_timer(mac,
+ eLIM_AUTH_SAE_TIMER);
+ /* success */
+ if (sae_msg->sae_status == IEEE80211_STATUS_SUCCESS)
+ lim_restore_from_auth_state(mac,
+ eSIR_SME_SUCCESS,
+ eSIR_MAC_SUCCESS_STATUS,
+ session);
+ else
+ lim_restore_from_auth_state(mac,
+ eSIR_SME_AUTH_REFUSED,
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ session);
+ break;
+ default:
+ /* SAE msg is received in unexpected state */
+ pe_err("received SAE msg in state %X",
+ session->limMlmState);
+ lim_print_mlm_state(mac, LOGE, session->limMlmState);
+ break;
+ }
+}
+#else
+static inline void lim_process_sae_msg(tpAniSirGlobal mac, void *body)
+{}
+#endif
+
/**
* lim_process_dual_mac_cfg_resp() - Process set dual mac config response
* @mac: Global MAC pointer
@@ -1661,6 +1728,7 @@
case SIR_LIM_DEAUTH_ACK_TIMEOUT:
case SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE:
case SIR_LIM_AUTH_RETRY_TIMEOUT:
+ case SIR_LIM_AUTH_SAE_TIMEOUT:
/* These timeout messages are handled by MLM sub module */
lim_process_mlm_req_messages(mac_ctx, msg);
break;
@@ -1972,6 +2040,16 @@
qdf_mem_free((void *)msg->bodyptr);
msg->bodyptr = NULL;
break;
+ case eWNI_SME_SEND_MGMT_FRAME_TX:
+ lim_send_mgmt_frame_tx(mac_ctx, msg->bodyptr);
+ qdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+ case eWNI_SME_SEND_SAE_MSG:
+ lim_process_sae_msg(mac_ctx, msg->bodyptr);
+ qdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
case WMA_SEND_BCN_RSP:
lim_send_bcn_rsp(mac_ctx, (tpSendbeaconParams)msg->bodyptr);
qdf_mem_free((void *)msg->bodyptr);
diff --git a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
index a938b60..41090c3 100644
--- a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -63,6 +63,48 @@
static void lim_process_auth_retry_timer(tpAniSirGlobal);
/**
+ * lim_process_sae_auth_timeout() - This function is called to process sae
+ * auth timeout
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * @Return: None
+ */
+static void lim_process_sae_auth_timeout(tpAniSirGlobal mac_ctx)
+{
+ tpPESession session;
+
+ session = pe_find_session_by_session_id(mac_ctx,
+ mac_ctx->lim.limTimers.sae_auth_timer.sessionId);
+ if (session == NULL) {
+ pe_err("Session does not exist for given session id");
+ return;
+ }
+
+ pe_warn("SAE auth timeout sessionid %d mlmstate %X SmeState %X",
+ session->peSessionId, session->limMlmState,
+ session->limSmeState);
+
+ switch (session->limMlmState) {
+ case eLIM_MLM_WT_SAE_AUTH_STATE:
+ /*
+ * SAE authentication is not completed. Restore from
+ * auth state.
+ */
+ if (session->pePersona == QDF_STA_MODE)
+ lim_restore_from_auth_state(mac_ctx,
+ eSIR_SME_AUTH_TIMEOUT_RESULT_CODE,
+ eSIR_MAC_UNSPEC_FAILURE_REASON, session);
+ break;
+ default:
+ /* SAE authentication is timed out in unexpected state */
+ pe_err("received unexpected SAE auth timeout in state %X",
+ session->limMlmState);
+ lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState);
+ break;
+ }
+}
+
+/**
* lim_process_mlm_req_messages() - process mlm request messages
* @mac_ctx: global MAC context
* @msg: mlm request message
@@ -146,6 +188,9 @@
case SIR_LIM_AUTH_RETRY_TIMEOUT:
lim_process_auth_retry_timer(mac_ctx);
break;
+ case SIR_LIM_AUTH_SAE_TIMEOUT:
+ lim_process_sae_auth_timeout(mac_ctx);
+ break;
case LIM_MLM_TSPEC_REQ:
default:
break;
@@ -520,7 +565,7 @@
addbss_param->rateSet.numRates = SIR_MAC_RATESET_EID_MAX;
}
qdf_mem_copy(addbss_param->rateSet.rate, mlm_start_req->rateSet.rate,
- addbss_param->rateSet.numRates);
+ mlm_start_req->rateSet.numRates);
addbss_param->nwType = mlm_start_req->nwType;
addbss_param->htCapable = mlm_start_req->htCapable;
@@ -1013,6 +1058,85 @@
return fl;
}
+#ifdef WLAN_FEATURE_SAE
+/**
+ * lim_process_mlm_auth_req_sae() - Handle SAE authentication
+ * @mac_ctx: global MAC context
+ * @session: PE session entry
+ *
+ * This function is called by lim_process_mlm_auth_req to handle SAE
+ * authentication.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS lim_process_mlm_auth_req_sae(tpAniSirGlobal mac_ctx,
+ tpPESession session)
+{
+ QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+ struct sir_sae_info *sae_info;
+ cds_msg_t msg;
+
+ sae_info = qdf_mem_malloc(sizeof(*sae_info));
+ if (sae_info == NULL) {
+ pe_err("Memory allocation failed");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ sae_info->msg_type = eWNI_SME_TRIGGER_SAE;
+ sae_info->msg_len = sizeof(*sae_info);
+ sae_info->vdev_id = session->smeSessionId;
+
+ qdf_mem_copy(sae_info->peer_mac_addr.bytes,
+ session->bssId,
+ QDF_MAC_ADDR_SIZE);
+
+ sae_info->ssid.length = session->ssId.length;
+ qdf_mem_copy(sae_info->ssid.ssId,
+ session->ssId.ssId,
+ session->ssId.length);
+
+ pe_debug("vdev_id %d ssid %.*s "MAC_ADDRESS_STR"",
+ sae_info->vdev_id,
+ sae_info->ssid.length,
+ sae_info->ssid.ssId,
+ MAC_ADDR_ARRAY(sae_info->peer_mac_addr.bytes));
+
+ msg.type = eWNI_SME_TRIGGER_SAE;
+ msg.bodyptr = sae_info;
+ msg.bodyval = 0;
+
+ qdf_status = mac_ctx->lim.sme_msg_callback(mac_ctx, &msg);
+ if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ pe_err("SAE failed for AUTH frame");
+ qdf_mem_free(sae_info);
+ return qdf_status;
+ }
+ session->limMlmState = eLIM_MLM_WT_SAE_AUTH_STATE;
+
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
+ session->limMlmState));
+
+ mac_ctx->lim.limTimers.sae_auth_timer.sessionId =
+ session->peSessionId;
+
+ /* Activate SAE auth timer */
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
+ session->peSessionId, eLIM_AUTH_SAE_TIMER));
+ if (tx_timer_activate(&mac_ctx->lim.limTimers.sae_auth_timer)
+ != TX_SUCCESS) {
+ pe_err("could not start Auth SAE timer");
+ }
+
+ return qdf_status;
+}
+#else
+static QDF_STATUS lim_process_mlm_auth_req_sae(tpAniSirGlobal mac_ctx,
+ tpPESession session)
+{
+ return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+
/**
* lim_process_mlm_auth_req() - process lim auth request
*
@@ -1100,13 +1224,33 @@
mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr);
session->limPrevMlmState = session->limMlmState;
- session->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE;
+
+ if ((mac_ctx->lim.gpLimMlmAuthReq->authType == eSIR_AUTH_TYPE_SAE) &&
+ !session->sae_pmk_cached) {
+ if (lim_process_mlm_auth_req_sae(mac_ctx, session) !=
+ QDF_STATUS_SUCCESS) {
+ mlm_auth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ } else {
+ pe_debug("lim_process_mlm_auth_req_sae is successful");
+ return;
+ }
+ } else
+ session->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE;
+
MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
session->limMlmState));
- /* Prepare & send Authentication frame */
- auth_frame_body.authAlgoNumber =
+ /* Mark auth algo as open when auth type is SAE and PMK is cached */
+ if ((mac_ctx->lim.gpLimMlmAuthReq->authType == eSIR_AUTH_TYPE_SAE) &&
+ session->sae_pmk_cached) {
+ auth_frame_body.authAlgoNumber = eSIR_OPEN_SYSTEM;
+ } else {
+ auth_frame_body.authAlgoNumber =
(uint8_t) mac_ctx->lim.gpLimMlmAuthReq->authType;
+ }
+
+ /* Prepare & send Authentication frame */
auth_frame_body.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
auth_frame_body.authStatusCode = 0;
#ifdef FEATURE_WLAN_DIAG_SUPPORT
@@ -1938,6 +2082,8 @@
mlm_set_keys_req = (tLimMlmSetKeysReq *) msg_buf;
if (mac_ctx->lim.gpLimMlmSetKeysReq != NULL) {
+ qdf_mem_zero(mac_ctx->lim.gpLimMlmSetKeysReq,
+ sizeof(tLimMlmSetKeysReq));
qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
}
@@ -1947,6 +2093,7 @@
mlm_set_keys_req->sessionId);
if (NULL == session) {
pe_err("session does not exist for given sessionId");
+ qdf_mem_zero(mlm_set_keys_req, sizeof(tLimMlmSetKeysReq));
qdf_mem_free(mlm_set_keys_req);
mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
return;
@@ -2013,6 +2160,8 @@
case eSIR_ED_GCMP_256:
#ifdef WLAN_FEATURE_11W
case eSIR_ED_AES_128_CMAC:
+ case eSIR_ED_AES_GMAC_128:
+ case eSIR_ED_AES_GMAC_256:
#endif
sta_idx = session->staId;
break;
diff --git a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
index 6b9b5b6..2f6e0e9 100644
--- a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
+++ b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -2722,6 +2722,7 @@
session_entry = pe_find_session_by_session_id(mac_ctx, session_id);
if (session_entry == NULL) {
pe_err("session does not exist for given session_id");
+ qdf_mem_zero(msg->bodyptr, sizeof(tSetStaKeyParams));
qdf_mem_free(msg->bodyptr);
msg->bodyptr = NULL;
lim_send_sme_set_context_rsp(mac_ctx,
@@ -2747,6 +2748,7 @@
else
mlm_set_key_cnf.key_len_nonzero = false;
+ qdf_mem_zero(msg->bodyptr, sizeof(tSetStaKeyParams));
qdf_mem_free(msg->bodyptr);
msg->bodyptr = NULL;
@@ -2765,6 +2767,8 @@
* Free the buffer cached for the global
* mac_ctx->lim.gpLimMlmSetKeysReq
*/
+ qdf_mem_zero(mac_ctx->lim.gpLimMlmSetKeysReq,
+ sizeof(tLimMlmSetKeysReq));
qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
}
@@ -2808,6 +2812,7 @@
if (session_entry == NULL) {
pe_err("session does not exist for given sessionId [%d]",
session_id);
+ qdf_mem_zero(msg->bodyptr, sizeof(tSetBssKeyParams));
qdf_mem_free(msg->bodyptr);
msg->bodyptr = NULL;
lim_send_sme_set_context_rsp(mac_ctx, set_key_cnf.peer_macaddr,
@@ -2844,6 +2849,7 @@
set_key_cnf.resultCode = result_status;
}
+ qdf_mem_zero(msg->bodyptr, sizeof(tSetBssKeyParams));
qdf_mem_free(msg->bodyptr);
msg->bodyptr = NULL;
/* Restore MLME state */
@@ -2864,6 +2870,8 @@
* Free the buffer cached for the
* global mac_ctx->lim.gpLimMlmSetKeysReq
*/
+ qdf_mem_zero(mac_ctx->lim.gpLimMlmSetKeysReq,
+ sizeof(tLimMlmSetKeysReq));
qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
}
diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
index 5bbc137..096bb85 100644
--- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1490,6 +1490,30 @@
qdf_mem_set(&pMac->lim.dfschannelList, sizeof(tSirDFSChannelList), 0);
}
+#ifdef WLAN_FEATURE_SAE
+/**
+ * lim_update_sae_config()- This API update SAE session info to csr config
+ * from join request.
+ * @session: PE session
+ * @sme_join_req: pointer to join request
+ *
+ * Return: None
+ */
+static void lim_update_sae_config(tpPESession session,
+ tpSirSmeJoinReq sme_join_req)
+{
+ session->sae_pmk_cached = sme_join_req->sae_pmk_cached;
+
+ pe_debug("pmk_cached %d for BSSID=" MAC_ADDRESS_STR,
+ session->sae_pmk_cached,
+ MAC_ADDR_ARRAY(sme_join_req->bssDescription.bssId));
+}
+#else
+static inline void lim_update_sae_config(tpPESession session,
+ tpSirSmeJoinReq sme_join_req)
+{}
+#endif
+
/**
* __lim_process_sme_join_req() - process SME_JOIN_REQ message
* @mac_ctx: Pointer to Global MAC structure
@@ -1772,7 +1796,13 @@
/* Record if management frames need to be protected */
#ifdef WLAN_FEATURE_11W
- if (eSIR_ED_AES_128_CMAC == sme_join_req->MgmtEncryptionType)
+ if ((eSIR_ED_AES_128_CMAC ==
+ sme_join_req->MgmtEncryptionType)
+#ifdef WLAN_FEATURE_GMAC
+ || (eSIR_ED_AES_GMAC_128 == sme_join_req->MgmtEncryptionType)
+ || (eSIR_ED_AES_GMAC_256 == sme_join_req->MgmtEncryptionType)
+#endif
+ )
session->limRmfEnabled = 1;
else
session->limRmfEnabled = 0;
@@ -1805,6 +1835,7 @@
sme_join_req->txLdpcIniFeatureEnabled;
lim_update_fils_config(session, sme_join_req);
+ lim_update_sae_config(session, sme_join_req);
if (session->bssType == eSIR_INFRASTRUCTURE_MODE) {
session->limSystemRole = eLIM_STA_ROLE;
} else {
@@ -2931,6 +2962,9 @@
}
qdf_mem_copy(set_context_req, msg_buf,
sizeof(struct sSirSmeSetContextReq));
+
+ qdf_mem_zero(msg_buf, sizeof(tSirSmeSetContextReq));
+
sme_session_id = set_context_req->sessionId;
sme_transaction_id = set_context_req->transactionId;
@@ -3038,6 +3072,7 @@
sme_transaction_id);
}
end:
+ qdf_mem_zero(set_context_req, sizeof(tSirSmeSetContextReq));
qdf_mem_free(set_context_req);
return;
}
@@ -4109,6 +4144,7 @@
local_ie_buf = qdf_mem_malloc(MAX_DEFAULT_SCAN_IE_LEN);
if (!local_ie_buf) {
pe_err("Mem Alloc failed for local_ie_buf");
+ qdf_mem_zero(req_buffer, sizeof(tSirRoamOffloadScanReq));
qdf_mem_free(req_buffer);
return;
}
@@ -4136,6 +4172,7 @@
status = wma_post_ctrl_msg(mac_ctx, &wma_msg);
if (eSIR_SUCCESS != status) {
pe_err("Posting WMA_ROAM_SCAN_OFFLOAD_REQ failed");
+ qdf_mem_zero(req_buffer, sizeof(tSirRoamOffloadScanReq));
qdf_mem_free(req_buffer);
}
}
diff --git a/core/mac/src/pe/lim/lim_security_utils.c b/core/mac/src/pe/lim/lim_security_utils.c
index ccf0201..66257ad 100644
--- a/core/mac/src/pe/lim/lim_security_utils.c
+++ b/core/mac/src/pe/lim/lim_security_utils.c
@@ -472,11 +472,17 @@
* retry is needed also cancel the auth rety timer
*/
pMac->auth_ack_status = LIM_AUTH_ACK_RCD_SUCCESS;
- /* 'Change' timer for future activations */
- lim_deactivate_and_change_timer(pMac, eLIM_AUTH_RETRY_TIMER);
+ /* Auth retry and AUth failure timers are not started for SAE */
/* 'Change' timer for future activations */
- lim_deactivate_and_change_timer(pMac, eLIM_AUTH_FAIL_TIMER);
+ if (tx_timer_running(&pMac->lim.limTimers.
+ g_lim_periodic_auth_retry_timer))
+ lim_deactivate_and_change_timer(pMac,
+ eLIM_AUTH_RETRY_TIMER);
+ /* 'Change' timer for future activations */
+ if (tx_timer_running(&pMac->lim.limTimers.gLimAuthFailureTimer))
+ lim_deactivate_and_change_timer(pMac,
+ eLIM_AUTH_FAIL_TIMER);
sir_copy_mac_addr(currentBssId, sessionEntry->bssId);
@@ -752,6 +758,7 @@
&pMlmSetKeysReq->peer_macaddr);
/* Free up buffer allocated for mlmSetKeysReq */
+ qdf_mem_zero(pMlmSetKeysReq, sizeof(tLimMlmSetKeysReq));
qdf_mem_free(pMlmSetKeysReq);
pMac->lim.gpLimMlmSetKeysReq = NULL;
@@ -856,6 +863,8 @@
/* Respond to SME with LIM_MLM_SETKEYS_CNF */
mlmSetKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ qdf_mem_zero(pSetBssKeyParams, sizeof(tSetBssKeyParams));
+ qdf_mem_free(pSetBssKeyParams);
} else
return; /* Continue after WMA_SET_BSSKEY_RSP... */
@@ -1028,6 +1037,7 @@
return; /* Continue after WMA_SET_STAKEY_RSP... */
free_sta_key:
+ qdf_mem_zero(pSetStaKeyParams, sizeof(tSetStaKeyParams));
qdf_mem_free(pSetStaKeyParams);
fail:
/* Respond to SME with LIM_MLM_SETKEYS_CNF */
diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c
index cb05cca..3ca92e8 100644
--- a/core/mac/src/pe/lim/lim_send_management_frames.c
+++ b/core/mac/src/pe/lim/lim_send_management_frames.c
@@ -4600,3 +4600,85 @@
return nSirStatus;
} /* End lim_send_sa_query_response_frame */
#endif
+
+/**
+ * lim_tx_mgmt_frame() - Transmits Auth mgmt frame
+ * @mac_ctx Pointer to Global MAC structure
+ * @mb_msg: Received message info
+ * @msg_len: Received message length
+ * @packet: Packet to be transmitted
+ * @frame: Received frame
+ *
+ * Return: None
+ */
+static void lim_tx_mgmt_frame(tpAniSirGlobal mac_ctx,
+ struct sir_mgmt_msg *mb_msg, uint32_t msg_len,
+ void *packet, uint8_t *frame)
+{
+ tpSirMacFrameCtl fc = (tpSirMacFrameCtl) mb_msg->data;
+ QDF_STATUS qdf_status;
+ uint8_t sme_session_id = 0;
+ tpPESession session;
+ uint16_t auth_ack_status;
+ enum rateid min_rid = RATEID_DEFAULT;
+
+ sme_session_id = mb_msg->session_id;
+ session = pe_find_session_by_sme_session_id(mac_ctx, sme_session_id);
+ if (session == NULL) {
+ pe_err("session not found for given sme session");
+ return;
+ }
+
+ MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ session->peSessionId, fc->subType));
+
+ mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
+ min_rid = lim_get_min_session_txrate(session);
+
+ qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
+ (uint16_t)msg_len,
+ TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
+ 7, lim_tx_complete, frame,
+ lim_auth_tx_complete_cnf,
+ 0, sme_session_id, false, 0, min_rid);
+ MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ session->peSessionId, qdf_status));
+ if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ pe_err("*** Could not send Auth frame, retCode=%X ***",
+ qdf_status);
+ mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
+ auth_ack_status = SENT_FAIL;
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_ACK_EVENT,
+ session, auth_ack_status, eSIR_FAILURE);
+ /* Pkt will be freed up by the callback */
+ }
+}
+
+void lim_send_mgmt_frame_tx(tpAniSirGlobal mac_ctx,
+ uint32_t *msg_buf)
+{
+ struct sir_mgmt_msg *mb_msg = (struct sir_mgmt_msg *)msg_buf;
+ uint32_t msg_len;
+ tpSirMacFrameCtl fc = (tpSirMacFrameCtl) mb_msg->data;
+ uint8_t sme_session_id;
+ QDF_STATUS qdf_status;
+ uint8_t *frame;
+ void *packet;
+
+ msg_len = mb_msg->msg_len - sizeof(*mb_msg);
+ pe_debug("sending fc->type: %d fc->subType: %d",
+ fc->type, fc->subType);
+
+ sme_session_id = mb_msg->session_id;
+
+ qdf_status = cds_packet_alloc((uint16_t) msg_len, (void **)&frame,
+ (void **)&packet);
+ if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ pe_err("call to bufAlloc failed for AUTH frame");
+ return;
+ }
+
+ qdf_mem_copy(frame, mb_msg->data, msg_len);
+
+ lim_tx_mgmt_frame(mac_ctx, mb_msg, msg_len, packet, frame);
+}
diff --git a/core/mac/src/pe/lim/lim_session.c b/core/mac/src/pe/lim/lim_session.c
index 70865f2..97748c8 100644
--- a/core/mac/src/pe/lim/lim_session.c
+++ b/core/mac/src/pe/lim/lim_session.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -839,6 +839,9 @@
pe_delete_fils_info(session);
session->valid = false;
+ qdf_mem_zero(session->WEPKeyMaterial,
+ sizeof(session->WEPKeyMaterial));
+
if (session->access_policy_vendor_ie)
qdf_mem_free(session->access_policy_vendor_ie);
diff --git a/core/mac/src/pe/lim/lim_timer_utils.c b/core/mac/src/pe/lim/lim_timer_utils.c
index aed0426..3f99f15 100644
--- a/core/mac/src/pe/lim/lim_timer_utils.c
+++ b/core/mac/src/pe/lim/lim_timer_utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -54,6 +54,11 @@
/* Lim Periodic Auth Retry timer default 60 ms */
#define LIM_AUTH_RETRY_TIMER_MS 60
+/*
+ * SAE auth timer of 5secs. This is required for duration of entire SAE
+ * authentication.
+ */
+#define LIM_AUTH_SAE_TIMER_MS 5000
/* This timer is a periodic timer which expires at every 1 sec to
convert ACTIVE DFS channel to DFS channels */
@@ -193,6 +198,20 @@
return false;
}
+ /*
+ * SAE auth timer of 5secs. This is required for duration of entire SAE
+ * authentication.
+ */
+ if ((tx_timer_create(pMac,
+ &pMac->lim.limTimers.sae_auth_timer,
+ "SAE AUTH Timer",
+ lim_timer_handler, SIR_LIM_AUTH_SAE_TIMEOUT,
+ SYS_MS_TO_TICKS(LIM_AUTH_SAE_TIMER_MS), 0,
+ TX_NO_ACTIVATE)) != TX_SUCCESS) {
+ pe_err("could not create SAE AUTH Timer");
+ return false;
+ }
+
return true;
}
/**
@@ -389,6 +408,7 @@
tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer);
+ tx_timer_delete(&pMac->lim.limTimers.sae_auth_timer);
if (NULL != pMac->lim.gLimPreAuthTimerTable.pTable) {
for (i = 0; i < pMac->lim.gLimPreAuthTimerTable.numEntry; i++)
@@ -959,6 +979,21 @@
}
break;
+ case eLIM_AUTH_SAE_TIMER:
+ if (tx_timer_deactivate
+ (&pMac->lim.limTimers.sae_auth_timer)
+ != TX_SUCCESS)
+ pe_err("Unable to deactivate SAE auth timer");
+
+ /* Change timer to reactivate it in future */
+ val = SYS_MS_TO_TICKS(LIM_AUTH_SAE_TIMER_MS);
+
+ if (tx_timer_change(&pMac->lim.limTimers.sae_auth_timer,
+ val, 0) != TX_SUCCESS)
+ pe_err("unable to change SAE auth timer");
+
+ break;
+
default:
/* Invalid timerId. Log error */
break;
diff --git a/core/mac/src/pe/lim/lim_timer_utils.h b/core/mac/src/pe/lim/lim_timer_utils.h
index c4fa197..c03ff4b 100644
--- a/core/mac/src/pe/lim/lim_timer_utils.h
+++ b/core/mac/src/pe/lim/lim_timer_utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, 2016, 2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -68,7 +68,8 @@
eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER,
eLIM_INSERT_SINGLESHOT_NOA_TIMER,
eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE,
- eLIM_AUTH_RETRY_TIMER
+ eLIM_AUTH_RETRY_TIMER,
+ eLIM_AUTH_SAE_TIMER
};
#define LIM_DISASSOC_DEAUTH_ACK_TIMEOUT 500
diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h
index 6dbceb4..bf5204a 100644
--- a/core/mac/src/pe/lim/lim_types.h
+++ b/core/mac/src/pe/lim/lim_types.h
@@ -1012,4 +1012,14 @@
void lim_process_assoc_failure_timeout(tpAniSirGlobal mac_ctx,
uint32_t msg_type);
+/**
+ * lim_send_mgmt_frame_tx() - Sends mgmt frame
+ * @mac_ctx Pointer to Global MAC structure
+ * @msg: Received message info
+ *
+ * Return: None
+ */
+void lim_send_mgmt_frame_tx(tpAniSirGlobal mac_ctx,
+ uint32_t *msg_buf);
+
#endif /* __LIM_TYPES_H */
diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c
index edf50b0..a944f59 100644
--- a/core/mac/src/pe/lim/lim_utils.c
+++ b/core/mac/src/pe/lim/lim_utils.c
@@ -619,6 +619,8 @@
tx_timer_deactivate(&lim_timer->
gLimActiveToPassiveChannelTimer);
+
+ tx_timer_deactivate(&lim_timer->sae_auth_timer);
}
@@ -705,6 +707,8 @@
tx_timer_delete(&lim_timer->
gLimActiveToPassiveChannelTimer);
+ tx_timer_delete(&lim_timer->sae_auth_timer);
+
mac_ctx->lim.gLimTimersCreated = 0;
}
} /*** end lim_cleanup_mlm() ***/
diff --git a/core/mac/src/pe/nan/nan_datapath.c b/core/mac/src/pe/nan/nan_datapath.c
index 6bf62c1..82b78e2 100644
--- a/core/mac/src/pe/nan/nan_datapath.c
+++ b/core/mac/src/pe/nan/nan_datapath.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -160,9 +160,8 @@
goto ndp_indication_failed;
}
}
- if (NDP_ROLE_RESPONDER == ndp_ind->role)
- lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_INDICATION,
- ndp_ind, sizeof(*ndp_ind), 0);
+ lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_INDICATION,
+ ndp_ind, sizeof(*ndp_ind), 0);
/*
* With NDP indication if peer does not exists already add_sta is
* executed resulting in new peer else no action is taken. Note that
@@ -172,13 +171,8 @@
* used by service layer to identify failure.
*/
ndp_indication_failed:
- /*
- * Free config if failure or for NDP_ROLE_INITIATOR role
- * As for success responder case this info is sent till HDD
- * and will be freed in sme.
- */
- if (status != QDF_STATUS_SUCCESS ||
- NDP_ROLE_INITIATOR == ndp_ind->role) {
+ /* free config and app info if failure */
+ if (status != QDF_STATUS_SUCCESS) {
qdf_mem_free(ndp_ind->ndp_config.ndp_cfg);
qdf_mem_free(ndp_ind->ndp_info.ndp_app_info);
ndp_ind->ndp_config.ndp_cfg = NULL;
diff --git a/core/mac/src/sys/legacy/src/utils/src/dot11f.c b/core/mac/src/sys/legacy/src/utils/src/dot11f.c
index 2275bb6..53199d5 100644
--- a/core/mac/src/sys/legacy/src/utils/src/dot11f.c
+++ b/core/mac/src/sys/legacy/src/utils/src/dot11f.c
@@ -8149,6 +8149,29 @@
#define SigIeWscReassocRes (0x007c)
+uint32_t dot11f_unpack_ie_dh_parameter_element(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEdh_parameter_element *pDst,
+ bool append_ie)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->group, pBuf, 2);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ pDst->num_public_key = (uint8_t)(ielen);
+ DOT11F_MEMCPY(pCtx, pDst->public_key, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_dh_parameter_element. */
+
+#define SigIedh_parameter_element (0x007d)
+
+
uint32_t dot11f_unpack_ie_ext_chan_switch_ann(tpAniSirGlobal pCtx,
uint8_t *pBuf,
uint8_t ielen,
@@ -8194,7 +8217,7 @@
return status;
} /* End dot11f_unpack_ie_ext_chan_switch_ann. */
-#define SigIeext_chan_switch_ann (0x007d)
+#define SigIeext_chan_switch_ann (0x007e)
uint32_t dot11f_unpack_ie_fils_assoc_delay_info(tpAniSirGlobal pCtx,
@@ -8218,7 +8241,7 @@
return status;
} /* End dot11f_unpack_ie_fils_assoc_delay_info. */
-#define SigIefils_assoc_delay_info (0x007e)
+#define SigIefils_assoc_delay_info (0x007f)
uint32_t dot11f_unpack_ie_fils_hlp_container(tpAniSirGlobal pCtx,
@@ -8254,7 +8277,7 @@
return status;
} /* End dot11f_unpack_ie_fils_hlp_container. */
-#define SigIefils_hlp_container (0x007f)
+#define SigIefils_hlp_container (0x0080)
uint32_t dot11f_unpack_ie_fils_indication(tpAniSirGlobal pCtx,
@@ -8292,7 +8315,7 @@
return status;
} /* End dot11f_unpack_ie_fils_indication. */
-#define SigIefils_indication (0x0080)
+#define SigIefils_indication (0x0081)
uint32_t dot11f_unpack_ie_fils_kde(tpAniSirGlobal pCtx,
@@ -8320,7 +8343,7 @@
return status;
} /* End dot11f_unpack_ie_fils_kde. */
-#define SigIefils_kde (0x0081)
+#define SigIefils_kde (0x0082)
uint32_t dot11f_unpack_ie_fils_key_confirmation(tpAniSirGlobal pCtx,
@@ -8340,7 +8363,7 @@
return status;
} /* End dot11f_unpack_ie_fils_key_confirmation. */
-#define SigIefils_key_confirmation (0x0082)
+#define SigIefils_key_confirmation (0x0083)
uint32_t dot11f_unpack_ie_fils_nonce(tpAniSirGlobal pCtx,
@@ -8364,7 +8387,7 @@
return status;
} /* End dot11f_unpack_ie_fils_nonce. */
-#define SigIefils_nonce (0x0083)
+#define SigIefils_nonce (0x0084)
uint32_t dot11f_unpack_ie_fils_public_key(tpAniSirGlobal pCtx,
@@ -8392,7 +8415,7 @@
return status;
} /* End dot11f_unpack_ie_fils_public_key. */
-#define SigIefils_public_key (0x0084)
+#define SigIefils_public_key (0x0085)
uint32_t dot11f_unpack_ie_fils_session(tpAniSirGlobal pCtx,
@@ -8416,7 +8439,7 @@
return status;
} /* End dot11f_unpack_ie_fils_session. */
-#define SigIefils_session (0x0085)
+#define SigIefils_session (0x0086)
uint32_t dot11f_unpack_ie_fils_wrapped_data(tpAniSirGlobal pCtx,
@@ -8436,7 +8459,7 @@
return status;
} /* End dot11f_unpack_ie_fils_wrapped_data. */
-#define SigIefils_wrapped_data (0x0086)
+#define SigIefils_wrapped_data (0x0087)
uint32_t dot11f_unpack_ie_fragment_ie(tpAniSirGlobal pCtx,
@@ -8456,7 +8479,7 @@
return status;
} /* End dot11f_unpack_ie_fragment_ie. */
-#define SigIefragment_ie (0x0087)
+#define SigIefragment_ie (0x0088)
uint32_t dot11f_unpack_ie_hs20vendor_ie(tpAniSirGlobal pCtx,
@@ -8513,7 +8536,7 @@
return status;
} /* End dot11f_unpack_ie_hs20vendor_ie. */
-#define SigIehs20vendor_ie (0x0088)
+#define SigIehs20vendor_ie (0x0089)
uint32_t dot11f_unpack_ie_ht2040_bss_coexistence(tpAniSirGlobal pCtx,
@@ -8544,7 +8567,7 @@
return status;
} /* End dot11f_unpack_ie_ht2040_bss_coexistence. */
-#define SigIeht2040_bss_coexistence (0x0089)
+#define SigIeht2040_bss_coexistence (0x008a)
uint32_t dot11f_unpack_ie_ht2040_bss_intolerant_report(tpAniSirGlobal pCtx,
@@ -8577,7 +8600,7 @@
return status;
} /* End dot11f_unpack_ie_ht2040_bss_intolerant_report. */
-#define SigIeht2040_bss_intolerant_report (0x008a)
+#define SigIeht2040_bss_intolerant_report (0x008b)
uint32_t dot11f_unpack_ie_osen_ie(tpAniSirGlobal pCtx,
@@ -8597,7 +8620,7 @@
return status;
} /* End dot11f_unpack_ie_osen_ie. */
-#define SigIeosen_ie (0x008b)
+#define SigIeosen_ie (0x008c)
uint32_t dot11f_unpack_ie_sec_chan_offset_ele(tpAniSirGlobal pCtx,
@@ -8621,7 +8644,7 @@
return status;
} /* End dot11f_unpack_ie_sec_chan_offset_ele. */
-#define SigIesec_chan_offset_ele (0x008c)
+#define SigIesec_chan_offset_ele (0x008d)
static const tFFDefn FFS_vendor_vht_ie[] = {
@@ -8670,7 +8693,7 @@
return status;
} /* End dot11f_unpack_ie_vendor_vht_ie. */
-#define SigIevendor_vht_ie (0x008d)
+#define SigIevendor_vht_ie (0x008e)
static const tFFDefn FFS_AddTSRequest[] = {
@@ -8882,6 +8905,10 @@
offsetof(tDot11fIEfragment_ie, present), 0, "fragment_ie",
0, 2, 257, SigIefragment_ie, {0, 0, 0, 0, 0},
0, DOT11F_EID_FRAGMENT_IE, 0, 0, },
+ { offsetof(tDot11fAssocRequest, dh_parameter_element),
+ offsetof(tDot11fIEdh_parameter_element, present), 0,
+ "dh_parameter_element", 0, 4, 259, SigIedh_parameter_element,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_DH_PARAMETER_ELEMENT, 32, 0, },
{ offsetof(tDot11fAssocRequest, WPAOpaque), offsetof(tDot11fIEWPAOpaque,
present), 0, "WPAOpaque", 0, 8, 255, SigIeWPAOpaque, {0, 80, 242, 1, 0},
4, DOT11F_EID_WPAOPAQUE, 0, 0, },
@@ -13264,6 +13291,16 @@
countOffset),
append_ie);
break;
+ case SigIedh_parameter_element:
+ status |=
+ dot11f_unpack_ie_dh_parameter_element(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEdh_parameter_element *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEdh_parameter_element) *
+ countOffset),
+ append_ie);
+ break;
case SigIeext_chan_switch_ann:
status |=
dot11f_unpack_ie_ext_chan_switch_ann(
@@ -16200,6 +16237,15 @@
(pFrm + pIe->offset + offset * i),
pnNeeded);
break;
+ case SigIedh_parameter_element:
+ offset = sizeof(tDot11fIEdh_parameter_element);
+ byteCount = ((tDot11fIEdh_parameter_element *)
+ (pFrm + pIe->offset + offset * i))->
+ num_public_key + 2;
+ pIePresent = ((tDot11fIEdh_parameter_element *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
case SigIeext_chan_switch_ann:
offset = sizeof(tDot11fIEext_chan_switch_ann);
byteCount = 4;
@@ -24279,6 +24325,40 @@
return status;
} /* End dot11f_pack_ie_wsc_reassoc_res. */
+uint32_t dot11f_pack_ie_dh_parameter_element(tpAniSirGlobal pCtx,
+ tDot11fIEdh_parameter_element *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_public_key + 2);
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 255;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 32;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->group, 2);
+ *pnConsumed += 2;
+ pBuf += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->public_key), pSrc->num_public_key);
+ *pnConsumed += pSrc->num_public_key;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_dh_parameter_element. */
+
uint32_t dot11f_pack_ie_ext_chan_switch_ann(tpAniSirGlobal pCtx,
tDot11fIEext_chan_switch_ann *pSrc,
uint8_t *pBuf,
@@ -26847,6 +26927,14 @@
sizeof(tDot11fIEWscReassocRes) * i),
pBufRemaining, nBufRemaining, &len);
break;
+ case SigIedh_parameter_element:
+ status |=
+ dot11f_pack_ie_dh_parameter_element(
+ pCtx, (tDot11fIEdh_parameter_element *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEdh_parameter_element) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
case SigIeext_chan_switch_ann:
status |=
dot11f_pack_ie_ext_chan_switch_ann(
diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
index b053f46..d769d04 100644
--- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
+++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
@@ -425,6 +425,9 @@
CASE_RETURN_STRING(eWNI_SME_GET_PEER_INFO_IND);
CASE_RETURN_STRING(eWNI_SME_GET_PEER_INFO_EXT_IND);
CASE_RETURN_STRING(eWNI_SME_RSO_CMD_STATUS_IND);
+ CASE_RETURN_STRING(eWNI_SME_TRIGGER_SAE);
+ CASE_RETURN_STRING(eWNI_SME_SEND_MGMT_FRAME_TX);
+ CASE_RETURN_STRING(eWNI_SME_SEND_SAE_MSG);
CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END);
default:
return (uint8_t *) "UNKNOWN";
@@ -780,6 +783,7 @@
CASE_RETURN_STRING(SIR_LIM_DEAUTH_ACK_TIMEOUT);
CASE_RETURN_STRING(SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT);
CASE_RETURN_STRING(SIR_LIM_AUTH_RETRY_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_AUTH_SAE_TIMEOUT);
CASE_RETURN_STRING(SIR_LIM_MSG_TYPES_END);
CASE_RETURN_STRING(LIM_MLM_SCAN_REQ);
CASE_RETURN_STRING(LIM_MLM_SCAN_CNF);
diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c
index 043067e..fe44364 100644
--- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c
+++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c
@@ -4616,7 +4616,7 @@
if (addts.num_WMMTCLAS) {
j = (uint8_t) (pAddTs->numTclas + addts.num_WMMTCLAS);
- if (SIR_MAC_TCLASIE_MAXNUM < j)
+ if (SIR_MAC_TCLASIE_MAXNUM > j)
j = SIR_MAC_TCLASIE_MAXNUM;
for (i = pAddTs->numTclas; i < j; ++i) {
@@ -4776,7 +4776,7 @@
if (addts.num_WMMTCLAS) {
j = (uint8_t) (pAddTs->numTclas + addts.num_WMMTCLAS);
- if (SIR_MAC_TCLASIE_MAXNUM < j)
+ if (SIR_MAC_TCLASIE_MAXNUM > j)
j = SIR_MAC_TCLASIE_MAXNUM;
for (i = pAddTs->numTclas; i < j; ++i) {
diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h
index 8fc9347..e99ad1d 100644
--- a/core/sme/inc/csr_api.h
+++ b/core/sme/inc/csr_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -47,6 +47,7 @@
/* MAC layer authentication types */
eCSR_AUTH_TYPE_OPEN_SYSTEM,
eCSR_AUTH_TYPE_SHARED_KEY,
+ eCSR_AUTH_TYPE_SAE,
eCSR_AUTH_TYPE_AUTOSWITCH,
/* Upper layer authentication types */
@@ -70,6 +71,10 @@
eCSR_AUTH_TYPE_FILS_SHA384,
eCSR_AUTH_TYPE_FT_FILS_SHA256,
eCSR_AUTH_TYPE_FT_FILS_SHA384,
+ eCSR_AUTH_TYPE_OWE,
+ eCSR_AUTH_TYPE_SUITEB_EAP_SHA256,
+ eCSR_AUTH_TYPE_SUITEB_EAP_SHA384,
+ eCSR_AUTH_TYPE_DPP_RSN,
eCSR_NUM_OF_SUPPORT_AUTH_TYPE,
eCSR_AUTH_TYPE_FAILED = 0xff,
eCSR_AUTH_TYPE_UNKNOWN = eCSR_AUTH_TYPE_FAILED,
@@ -94,10 +99,9 @@
eCSR_ENCRYPT_TYPE_BTK,
#endif
#endif /* FEATURE_WLAN_ESE */
-#ifdef WLAN_FEATURE_11W
- /* 11w BIP */
eCSR_ENCRYPT_TYPE_AES_CMAC,
-#endif
+ eCSR_ENCRYPT_TYPE_AES_GMAC_128,
+ eCSR_ENCRYPT_TYPE_AES_GMAC_256,
eCSR_ENCRYPT_TYPE_AES_GCMP,
eCSR_ENCRYPT_TYPE_AES_GCMP_256,
eCSR_ENCRYPT_TYPE_ANY,
@@ -227,6 +231,8 @@
#define CSR_AES_KEY_LEN 16
#define CSR_AES_GCMP_KEY_LEN 16
#define CSR_AES_GCMP_256_KEY_LEN 32
+#define CSR_AES_GMAC_128_KEY_LEN 16
+#define CSR_AES_GMAC_256_KEY_LEN 32
#define CSR_MAX_TX_POWER (WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX)
#define CSR_MAX_RSC_LEN 16
#ifdef FEATURE_WLAN_WAPI
@@ -539,6 +545,9 @@
eCSR_ROAM_START,
eCSR_ROAM_ABORT,
eCSR_ROAM_NAPI_OFF,
+ eCSR_ROAM_SAE_COMPUTE,
+ /* LFR3 Roam sync complete */
+ eCSR_ROAM_SYNCH_COMPLETE,
} eRoamCmdStatus;
/* comment inside indicates what roaming callback gets */
@@ -937,6 +946,7 @@
uint8_t MFPRequired;
uint8_t MFPCapable;
#endif
+ tAniEdType mgmt_encryption_type;
tCsrKeys Keys;
tCsrChannelInfo ChannelInfo;
uint8_t operationChannel;
@@ -1556,6 +1566,9 @@
int rssi;
int tx_rate;
int rx_rate;
+#ifdef WLAN_FEATURE_SAE
+ struct sir_sae_info *sae_info;
+#endif
} tCsrRoamInfo;
typedef struct tagCsrFreqScanInfo {
@@ -1804,6 +1817,20 @@
(eCSR_AUTH_TYPE_FT_FILS_SHA256 == auth_type) || \
(eCSR_AUTH_TYPE_FT_FILS_SHA384 == auth_type))
+#ifdef WLAN_FEATURE_OWE
+#define CSR_IS_AUTH_TYPE_OWE(auth_type) \
+ (eCSR_AUTH_TYPE_OWE == auth_type)
+#else
+#define CSR_IS_AUTH_TYPE_OWE(auth_type) (false)
+#endif
+
+#ifdef WLAN_FEATURE_SAE
+#define CSR_IS_AUTH_TYPE_SAE(auth_type) \
+ (eCSR_AUTH_TYPE_SAE == auth_type)
+#else
+#define CSR_IS_AUTH_TYPE_SAE(auth_type) (false)
+#endif
+
QDF_STATUS csr_set_channels(tHalHandle hHal, tCsrConfigParam *pParam);
QDF_STATUS csr_set_reg_info(tHalHandle hHal, uint8_t *apCntryCode);
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
index b74ab7c..5d51a47 100644
--- a/core/sme/inc/sme_api.h
+++ b/core/sme/inc/sme_api.h
@@ -2246,14 +2246,6 @@
sme_get_roam_scan_stats(tHalHandle hal, roam_scan_stats_cb cb, void *context,
uint32_t vdev_id);
-/**
- * sme_get_scan_id() - Sme wrapper to get scan ID
- * @scan_id: output pointer to hold scan_id
- *
- * Return: QDF_STATUS
- */
-QDF_STATUS sme_get_scan_id(uint32_t *scan_id);
-
/*
* sme_validate_channel_list() - Validate the given channel list
* @hal: handle to global hal context
@@ -2267,5 +2259,35 @@
bool sme_validate_channel_list(tHalHandle hal,
uint8_t *chan_list,
uint8_t num_channels);
+/**
+ * sme_send_mgmt_tx() - Sends mgmt frame from CSR to LIM
+ * @hal: The handle returned by mac_open
+ * @session_id: session id
+ * @buf: pointer to frame
+ * @len: frame length
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_send_mgmt_tx(tHalHandle hal, uint8_t session_id,
+ const uint8_t *buf, uint32_t len);
+
+#ifdef WLAN_FEATURE_SAE
+/**
+ * sme_handle_sae_msg() - Sends SAE message received from supplicant
+ * @hal: The handle returned by mac_open
+ * @session_id: session id
+ * @sae_status: status of SAE authentication
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_handle_sae_msg(tHalHandle hal, uint8_t session_id,
+ uint8_t sae_status);
+#else
+static inline QDF_STATUS sme_handle_sae_msg(tHalHandle hal, uint8_t session_id,
+ uint8_t sae_status)
+{
+ return QDF_STATUS_SUCCESS;
+}
+#endif
#endif /* #if !defined( __SME_API_H ) */
diff --git a/core/sme/inc/sme_ft_api.h b/core/sme/inc/sme_ft_api.h
index 3b0ff3a..09ba335 100644
--- a/core/sme/inc/sme_ft_api.h
+++ b/core/sme/inc/sme_ft_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016,2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -94,6 +94,15 @@
uint16_t *ft_ies_length);
void sme_get_rici_es(tHalHandle hHal, uint32_t sessionId, uint8_t *ric_ies,
uint32_t ric_ies_ip_len, uint32_t *ric_ies_length);
+/**
+ * sme_reset_key() -Reset key information
+ * @mac_handle: MAC handle
+ * @vdev_id: vdev identifier
+ *
+ * Return: None
+ */
+void sme_reset_key(tHalHandle mac_handle, uint32_t vdev_id);
+
void sme_preauth_reassoc_intvl_timer_callback(void *context);
void sme_set_ft_pre_auth_state(tHalHandle hHal, uint32_t sessionId, bool state);
bool sme_get_ft_pre_auth_state(tHalHandle hHal, uint32_t sessionId);
diff --git a/core/sme/inc/sme_trace.h b/core/sme/inc/sme_trace.h
index 61ea3d2..cbeddaa 100644
--- a/core/sme/inc/sme_trace.h
+++ b/core/sme/inc/sme_trace.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, 2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -144,6 +144,7 @@
TRACE_CODE_SME_RX_HDD_LPHB_CONFIG_REQ,
#endif /* FEATURE_WLAN_LPHB */
TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE,
+ TRACE_CODE_SME_RX_HDD_SEND_MGMT_TX,
/*
* New trace commands to be added before this comment not at the end
* Trace codes for SME commands
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index e7eaa47..6f8a4d3 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -9354,6 +9354,7 @@
status = wma_post_ctrl_msg(mac_ctx, &wma_msg);
if (eSIR_SUCCESS != status) {
sme_err("Posting WMA_ROAM_SCAN_OFFLOAD_REQ failed");
+ qdf_mem_zero(req, sizeof(tSirRoamOffloadScanReq));
qdf_mem_free(req);
return QDF_STATUS_E_FAULT;
}
@@ -18380,8 +18381,10 @@
cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
sme_err("Not able to post message to WDA");
- if (pmk_cache)
+ if (pmk_cache) {
+ qdf_mem_zero(pmk_cache, sizeof(*pmk_cache));
qdf_mem_free(pmk_cache);
+ }
return QDF_STATUS_E_FAILURE;
}
@@ -19395,8 +19398,86 @@
}
return true;
}
-
-QDF_STATUS sme_get_scan_id(uint32_t *scan_id)
+/**
+ * sme_prepare_mgmt_tx() - Prepares mgmt frame
+ * @hal: The handle returned by mac_open
+ * @session_id: session id
+ * @buf: pointer to frame
+ * @len: frame length
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS sme_prepare_mgmt_tx(tHalHandle hal, uint8_t session_id,
+ const uint8_t *buf, uint32_t len)
{
- return wma_get_scan_id(scan_id);
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ struct sir_mgmt_msg *msg;
+ uint16_t msg_len;
+
+ sme_debug("prepares auth frame");
+
+ msg_len = sizeof(*msg) + len;
+ msg = qdf_mem_malloc(msg_len);
+ if (msg == NULL) {
+ status = QDF_STATUS_E_NOMEM;
+ } else {
+ msg->type = eWNI_SME_SEND_MGMT_FRAME_TX;
+ msg->msg_len = msg_len;
+ msg->session_id = session_id;
+ msg->data = (uint8_t *)msg + sizeof(*msg);
+ qdf_mem_copy(msg->data, buf, len);
+
+ status = cds_send_mb_message_to_mac(msg);
+ }
+ return status;
}
+
+QDF_STATUS sme_send_mgmt_tx(tHalHandle hal, uint8_t session_id,
+ const uint8_t *buf, uint32_t len)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+ MTRACE(qdf_trace(QDF_MODULE_ID_SME,
+ TRACE_CODE_SME_RX_HDD_SEND_MGMT_TX, session_id, 0));
+
+ status = sme_acquire_global_lock(&mac->sme);
+ if (QDF_IS_STATUS_SUCCESS(status)) {
+ status = sme_prepare_mgmt_tx(hal, session_id, buf, len);
+ sme_release_global_lock(&mac->sme);
+ }
+
+ return status;
+}
+
+#ifdef WLAN_FEATURE_SAE
+QDF_STATUS sme_handle_sae_msg(tHalHandle hal, uint8_t session_id,
+ uint8_t sae_status)
+{
+ QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+ struct sir_sae_msg *sae_msg;
+
+ qdf_status = sme_acquire_global_lock(&mac->sme);
+ if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ sae_msg = qdf_mem_malloc(sizeof(*sae_msg));
+ if (!sae_msg) {
+ qdf_status = QDF_STATUS_E_NOMEM;
+ sme_err("SAE: memory allocation failed");
+ } else {
+ sae_msg->message_type = eWNI_SME_SEND_SAE_MSG;
+ sae_msg->length = sizeof(*sae_msg);
+ sae_msg->session_id = session_id;
+ sae_msg->sae_status = sae_status;
+ sme_debug("SAE: sae_status %d session_id %d",
+ sae_msg->sae_status,
+ sae_msg->session_id);
+
+ qdf_status = cds_send_mb_message_to_mac(sae_msg);
+ }
+ sme_release_global_lock(&mac->sme);
+ }
+
+ return qdf_status;
+}
+#endif
diff --git a/core/sme/src/common/sme_ft_api.c b/core/sme/src/common/sme_ft_api.c
index bbfcaf1..325dad5 100644
--- a/core/sme/src/common/sme_ft_api.c
+++ b/core/sme/src/common/sme_ft_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017,2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -480,6 +480,24 @@
pUsrCtx->sessionId);
}
+void sme_reset_key(tHalHandle mac_handle, uint32_t vdev_id)
+{
+ tpAniSirGlobal mac = PMAC_STRUCT(mac_handle);
+ tCsrRoamSession *session = NULL;
+
+ if (!mac) {
+ sme_err("mac is NULL");
+ return;
+ }
+
+ session = CSR_GET_SESSION(mac, vdev_id);
+ if (!session)
+ return;
+ qdf_mem_zero(&session->psk_pmk, sizeof(session->psk_pmk));
+ session->pmk_len = 0;
+ qdf_mem_zero(&session->eseCckmInfo, sizeof(session->eseCckmInfo));
+}
+
/* Reset the FT context. */
void sme_ft_reset(tHalHandle hHal, uint32_t sessionId)
{
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index a182c4c..a137c90 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -118,6 +118,60 @@
/* Static Type declarations */
static tCsrRoamSession csr_roam_roam_session[CSR_ROAM_SESSION_MAX];
+#ifdef WLAN_FEATURE_SAE
+/**
+ * csr_sae_callback - Update SAE info to CSR roam session
+ * @mac_ctx: MAC context
+ * @msg_ptr: pointer to SAE message
+ *
+ * API to update SAE info to roam csr session
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS csr_sae_callback(tpAniSirGlobal mac_ctx,
+ tSirSmeRsp *msg_ptr)
+{
+ tCsrRoamInfo *roam_info;
+ uint32_t session_id;
+ struct sir_sae_info *sae_info;
+
+ sae_info = (struct sir_sae_info *) msg_ptr;
+ if (!sae_info) {
+ sme_err("SAE info is NULL");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ sme_debug("vdev_id %d "MAC_ADDRESS_STR"",
+ sae_info->vdev_id,
+ MAC_ADDR_ARRAY(sae_info->peer_mac_addr.bytes));
+
+ session_id = sae_info->vdev_id;
+ if (session_id == CSR_SESSION_ID_INVALID)
+ return QDF_STATUS_E_INVAL;
+
+ roam_info = qdf_mem_malloc(sizeof(*roam_info));
+ if (!roam_info) {
+ sme_err("qdf_mem_malloc failed for SAE");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ roam_info->sae_info = sae_info;
+
+ csr_roam_call_callback(mac_ctx, session_id, roam_info,
+ 0, eCSR_ROAM_SAE_COMPUTE,
+ eCSR_ROAM_RESULT_NONE);
+ qdf_mem_free(roam_info);
+
+ return QDF_STATUS_SUCCESS;
+}
+#else
+static inline QDF_STATUS csr_sae_callback(tpAniSirGlobal mac_ctx,
+ tSirSmeRsp *msg_ptr)
+{
+ return QDF_STATUS_SUCCESS;
+}
+#endif
+
#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
int diag_auth_type_from_csr_type(eCsrAuthType authType)
{
@@ -4412,8 +4466,9 @@
pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
}
- sme_debug("phyMode=%d, uCfgDot11Mode=%d",
- pProfile->phyMode, pBssConfig->uCfgDot11Mode);
+ sme_debug("phyMode=%d, uCfgDot11Mode=%d negotiatedAuthType %d",
+ pProfile->phyMode, pBssConfig->uCfgDot11Mode,
+ pProfile->negotiatedAuthType);
/* Qos */
if ((pBssConfig->uCfgDot11Mode != eCSR_CFG_DOT11_MODE_11N) &&
@@ -4449,6 +4504,9 @@
case eCSR_AUTH_TYPE_AUTOSWITCH:
pBssConfig->authType = eSIR_AUTO_SWITCH;
break;
+ case eCSR_AUTH_TYPE_SAE:
+ pBssConfig->authType = eSIR_AUTH_TYPE_SAE;
+ break;
}
/* short slot time */
if (eCSR_CFG_DOT11_MODE_11B != cfgDot11Mode)
@@ -4588,6 +4646,9 @@
case eCSR_AUTH_TYPE_AUTOSWITCH:
pBssConfig->authType = eSIR_AUTO_SWITCH;
break;
+ case eCSR_AUTH_TYPE_SAE:
+ pBssConfig->authType = eSIR_AUTH_TYPE_SAE;
+ break;
}
/* short slot time */
if (WNI_CFG_PHY_MODE_11B != pBssConfig->uCfgDot11Mode) {
@@ -4639,6 +4700,27 @@
return status;
}
+static void csr_reset_cfg_privacy(tpAniSirGlobal pMac)
+{
+ uint8_t Key0[WNI_CFG_WEP_DEFAULT_KEY_1_LEN] = {0};
+ uint8_t Key1[WNI_CFG_WEP_DEFAULT_KEY_2_LEN] = {0};
+ uint8_t Key2[WNI_CFG_WEP_DEFAULT_KEY_3_LEN] = {0};
+ uint8_t Key3[WNI_CFG_WEP_DEFAULT_KEY_4_LEN] = {0};
+
+ cfg_set_int(pMac, WNI_CFG_PRIVACY_ENABLED, 0);
+ cfg_set_int(pMac, WNI_CFG_RSN_ENABLED, 0);
+ cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_1, Key0,
+ WNI_CFG_WEP_DEFAULT_KEY_1_LEN);
+ cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_2, Key1,
+ WNI_CFG_WEP_DEFAULT_KEY_2_LEN);
+ cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_3, Key2,
+ WNI_CFG_WEP_DEFAULT_KEY_3_LEN);
+ cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_4, Key3,
+ WNI_CFG_WEP_DEFAULT_KEY_4_LEN);
+ cfg_set_int(pMac, WNI_CFG_WEP_KEY_LENGTH, 0);
+ cfg_set_int(pMac, WNI_CFG_WEP_DEFAULT_KEYID, 0);
+}
+
void csr_set_cfg_privacy(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile,
bool fPrivacy)
{
@@ -5297,7 +5379,7 @@
static
QDF_STATUS csr_roam_stop_network(tpAniSirGlobal pMac, uint32_t sessionId,
- tCsrRoamProfile *pProfile,
+ tCsrRoamProfile *roam_profile,
tSirBssDescription *pBssDesc,
tDot11fBeaconIEs *pIes)
{
@@ -5316,7 +5398,7 @@
sme_debug("session id: %d", sessionId);
- status = csr_roam_prepare_bss_config(pMac, pProfile, pBssDesc,
+ status = csr_roam_prepare_bss_config(pMac, roam_profile, pBssDesc,
pBssConfig, pIes);
if (QDF_IS_STATUS_SUCCESS(status)) {
eCsrRoamSubState substate;
@@ -5326,10 +5408,11 @@
/* This will allow to pass cbMode during join req */
pSession->bssParams.cbMode = pBssConfig->cbMode;
/* For IBSS, we need to prepare some more information */
- if (csr_is_bss_type_ibss(pProfile->BSSType) ||
- CSR_IS_INFRA_AP(pProfile))
- csr_roam_prepare_bss_params(pMac, sessionId, pProfile,
- pBssDesc, pBssConfig, pIes);
+ if (csr_is_bss_type_ibss(roam_profile->BSSType) ||
+ CSR_IS_INFRA_AP(roam_profile))
+ csr_roam_prepare_bss_params(pMac, sessionId,
+ roam_profile, pBssDesc,
+ pBssConfig, pIes);
/*
* If we are in an IBSS, then stop the IBSS...
@@ -5359,22 +5442,22 @@
* parameters for this Bss.
*/
status = csr_roam_set_bss_config_cfg(pMac,
- sessionId, pProfile, pBssDesc,
- pBssConfig, pIes, false);
- } else if (pBssDesc ||
- CSR_IS_INFRA_AP(pProfile)) {
+ sessionId, roam_profile,
+ pBssDesc, pBssConfig, pIes,
+ false);
+ } else if (pBssDesc || CSR_IS_INFRA_AP(roam_profile)) {
/*
* Neither in IBSS nor in Infra. We can go ahead and set
* the cfg for tne new network... nothing to stop.
*/
- bool is11rRoamingFlag = false;
+ bool is_11r_roamingFlag = false;
- is11rRoamingFlag = csr_roam_is11r_assoc(pMac,
+ is_11r_roamingFlag = csr_roam_is11r_assoc(pMac,
sessionId);
/* Set parameters for this Bss. */
status = csr_roam_set_bss_config_cfg(pMac, sessionId,
- pProfile, pBssDesc, pBssConfig, pIes,
- is11rRoamingFlag);
+ roam_profile, pBssDesc, pBssConfig,
+ pIes, is_11r_roamingFlag);
}
} /* Success getting BSS config info */
qdf_mem_free(pBssConfig);
@@ -5543,6 +5626,11 @@
pCommand->u.roamCmd.roamProfile.negotiatedAuthType =
eCSR_AUTH_TYPE_AUTOSWITCH;
break;
+
+ case eCSR_AUTH_TYPE_SAE:
+ pCommand->u.roamCmd.roamProfile.negotiatedAuthType =
+ eCSR_AUTH_TYPE_SAE;
+ break;
}
pCommand->u.roamCmd.roamProfile.negotiatedUCEncryptionType =
pCommand->u.roamCmd.roamProfile.EncryptionType.
@@ -6115,7 +6203,7 @@
QDF_STATUS csr_roam_process_command(tpAniSirGlobal pMac, tSmeCmd *pCommand)
{
- QDF_STATUS status = QDF_STATUS_SUCCESS;
+ QDF_STATUS lock_status, status = QDF_STATUS_SUCCESS;
tCsrRoamInfo roamInfo;
uint32_t sessionId = pCommand->sessionId;
tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
@@ -6138,7 +6226,18 @@
}
status = csr_roam_process_disassoc_deauth(pMac, pCommand,
true, false);
+ lock_status = sme_acquire_global_lock(&pMac->sme);
+ if (!QDF_IS_STATUS_SUCCESS(lock_status)) {
+ csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
+ /*
+ * Return success so that caller will not remove cmd
+ * again from smeCmdActiveList as it is already removed
+ * as part of csr_roam_complete.
+ */
+ return QDF_STATUS_SUCCESS;
+ }
csr_free_roam_profile(pMac, sessionId);
+ sme_release_global_lock(&pMac->sme);
break;
case eCsrSmeIssuedDisassocForHandoff:
/* Not to free pMac->roam.pCurRoamProfile (via
@@ -6151,12 +6250,34 @@
case eCsrForcedDisassocMICFailure:
status = csr_roam_process_disassoc_deauth(pMac, pCommand,
true, true);
+ lock_status = sme_acquire_global_lock(&pMac->sme);
+ if (!QDF_IS_STATUS_SUCCESS(lock_status)) {
+ csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
+ /*
+ * Return success so that caller will not remove cmd
+ * again from smeCmdActiveList as it is already removed
+ * as part of csr_roam_complete.
+ */
+ return QDF_STATUS_SUCCESS;
+ }
csr_free_roam_profile(pMac, sessionId);
+ sme_release_global_lock(&pMac->sme);
break;
case eCsrForcedDeauth:
status = csr_roam_process_disassoc_deauth(pMac, pCommand,
false, false);
+ lock_status = sme_acquire_global_lock(&pMac->sme);
+ if (!QDF_IS_STATUS_SUCCESS(lock_status)) {
+ csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
+ /*
+ * Return success so that caller will not remove cmd
+ * again from smeCmdActiveList as it is already removed
+ * as part of csr_roam_complete.
+ */
+ return QDF_STATUS_SUCCESS;
+ }
csr_free_roam_profile(pMac, sessionId);
+ sme_release_global_lock(&pMac->sme);
break;
case eCsrHddIssuedReassocToSameAP:
case eCsrSmeIssuedReassocToSameAP:
@@ -6216,6 +6337,17 @@
if (pCommand->u.roamCmd.fUpdateCurRoamProfile) {
/* Remember the roaming profile */
+ lock_status = sme_acquire_global_lock(&pMac->sme);
+ if (!QDF_IS_STATUS_SUCCESS(lock_status)) {
+ csr_roam_complete(pMac,
+ eCsrNothingToJoin, NULL);
+ /*
+ * Return success so that caller will not remove
+ * cmd again from smeCmdActiveList as it is
+ * already removed as part of csr_roam_complete.
+ */
+ return QDF_STATUS_SUCCESS;
+ }
csr_free_roam_profile(pMac, sessionId);
pSession->pCurRoamProfile =
qdf_mem_malloc(sizeof(tCsrRoamProfile));
@@ -6224,6 +6356,7 @@
pSession->pCurRoamProfile,
&pCommand->u.roamCmd.roamProfile);
}
+ sme_release_global_lock(&pMac->sme);
}
/*
* At this point original uapsd_mask is saved in
@@ -6548,7 +6681,7 @@
|| (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == authType) ||
(eCSR_AUTH_TYPE_RSN_8021X_SHA256 == authType)
#endif /* FEATURE_WLAN_WAPI */
- ) {
+ || (eCSR_AUTH_TYPE_SAE == authType)) {
if (!pIesLocal && !QDF_IS_STATUS_SUCCESS
(csr_get_parsed_bss_description_ies(pMac,
pSirBssDesc, &pIesLocal)))
@@ -10339,6 +10472,12 @@
case eWNI_SME_SETCONTEXT_RSP:
csr_roam_check_for_link_status_change(pMac, pSmeRsp);
break;
+
+ case eWNI_SME_TRIGGER_SAE:
+ sme_debug("Invoke SAE callback");
+ csr_sae_callback(pMac, pSmeRsp);
+ break;
+
default:
sme_debug("Unexpected message type: %d[0x%X] received in substate %s",
pSmeRsp->messageType, pSmeRsp->messageType,
@@ -10678,6 +10817,34 @@
CSR_AES_KEY_LEN);
*enqueue_cmd = true;
break;
+
+#ifdef WLAN_FEATURE_GMAC
+ case eCSR_ENCRYPT_TYPE_AES_GMAC_128:
+ if (set_key->keyLength < CSR_AES_GMAC_128_KEY_LEN) {
+ sme_warn("Invalid AES GMAC 128 keylength [= %d]",
+ set_key->keyLength);
+ *enqueue_cmd = false;
+ return QDF_STATUS_E_INVAL;
+ }
+ set_key_cmd->u.setKeyCmd.keyLength = CSR_AES_GMAC_128_KEY_LEN;
+ qdf_mem_copy(set_key_cmd->u.setKeyCmd.Key, set_key->Key,
+ CSR_AES_GMAC_128_KEY_LEN);
+ *enqueue_cmd = true;
+ break;
+
+ case eCSR_ENCRYPT_TYPE_AES_GMAC_256:
+ if (set_key->keyLength < CSR_AES_GMAC_256_KEY_LEN) {
+ sme_warn("Invalid AES GMAC 256 keylength [= %d]",
+ set_key->keyLength);
+ *enqueue_cmd = false;
+ return QDF_STATUS_E_INVAL;
+ }
+ set_key_cmd->u.setKeyCmd.keyLength = CSR_AES_GMAC_256_KEY_LEN;
+ qdf_mem_copy(set_key_cmd->u.setKeyCmd.Key, set_key->Key,
+ CSR_AES_GMAC_256_KEY_LEN);
+ *enqueue_cmd = true;
+ break;
+#endif
#endif /* WLAN_FEATURE_11W */
default:
/* for open security also we want to enqueue command */
@@ -14400,6 +14567,8 @@
sizeof(tPmkidCacheInfo) * CSR_MAX_PMKID_ALLOWED);
pSession->NumPmkidCache = 0;
pSession->curr_cache_idx = 0;
+ qdf_mem_zero(pSession->psk_pmk, sizeof(pSession->psk_pmk));
+ pSession->pmk_len = 0;
return QDF_STATUS_SUCCESS;
}
@@ -14933,8 +15102,13 @@
static void csr_set_mgmt_enc_type(tCsrRoamProfile *profile,
tDot11fBeaconIEs *ies, tSirSmeJoinReq *csr_join_req)
{
+ sme_debug("mgmt encryption type %d MFPe %d MFPr %d",
+ profile->mgmt_encryption_type,
+ profile->MFPEnabled, profile->MFPRequired);
+
if (profile->MFPEnabled)
- csr_join_req->MgmtEncryptionType = eSIR_ED_AES_128_CMAC;
+ csr_join_req->MgmtEncryptionType =
+ profile->mgmt_encryption_type;
else
csr_join_req->MgmtEncryptionType = eSIR_ED_NONE;
if (profile->MFPEnabled &&
@@ -14976,6 +15150,36 @@
{ }
#endif
+#ifdef WLAN_FEATURE_SAE
+/*
+ * csr_update_sae_config: Copy SAE info to join request
+ * @profile: pointer to profile
+ * @csr_join_req: csr join request
+ *
+ * Return: None
+ */
+static void csr_update_sae_config(tSirSmeJoinReq *csr_join_req,
+ tpAniSirGlobal mac, tCsrRoamSession *session)
+{
+ tPmkidCacheInfo pmkid_cache;
+ uint32_t index;
+
+ qdf_mem_copy(pmkid_cache.BSSID.bytes,
+ csr_join_req->bssDescription.bssId, QDF_MAC_ADDR_SIZE);
+
+ csr_join_req->sae_pmk_cached =
+ csr_lookup_pmkid_using_bssid(mac, session, &pmkid_cache, &index);
+
+ sme_debug("pmk_cached %d for BSSID=" MAC_ADDRESS_STR,
+ csr_join_req->sae_pmk_cached,
+ MAC_ADDR_ARRAY(csr_join_req->bssDescription.bssId));
+}
+#else
+static void csr_update_sae_config(tSirSmeJoinReq *csr_join_req,
+ tpAniSirGlobal mac, tCsrRoamSession *session)
+{ }
+#endif
+
/**
* The communication between HDD and LIM is thru mailbox (MB).
* Both sides will access the data structure "tSirSmeJoinReq".
@@ -15691,6 +15895,7 @@
pBssDescription->length +
sizeof(pBssDescription->length));
csr_update_fils_connection_info(pProfile, csr_join_req);
+ csr_update_sae_config(csr_join_req, pMac, pSession);
/*
* conc_custom_rule1:
* If SAP comes up first and STA comes up later then SAP
@@ -16351,8 +16556,10 @@
status = cds_mq_post_message_by_priority(
QDF_MODULE_ID_PE, &cds_msg,
LOW_PRIORITY);
- if (QDF_IS_STATUS_ERROR(status))
+ if (QDF_IS_STATUS_ERROR(status)) {
+ qdf_mem_zero(pMsg, msgLen);
qdf_mem_free(pMsg);
+ }
} while (0);
return status;
}
@@ -17158,6 +17365,8 @@
/* Clean up FT related data structures */
sme_ft_close(pMac, sessionId);
+ sme_reset_key((tHalHandle)pMac, sessionId);
+ csr_reset_cfg_privacy(pMac);
csr_free_connect_bss_desc(pMac, sessionId);
csr_roam_free_connect_profile(&pSession->connectedProfile);
csr_roam_free_connected_info(pMac, &pSession->connectedInfo);
@@ -19503,7 +19712,6 @@
{
struct roam_fils_params *roam_fils_params;
struct cds_fils_connection_info *fils_info;
- uint32_t usr_name_len;
if (!session->pCurRoamProfile)
return;
@@ -19525,19 +19733,11 @@
return;
}
- usr_name_len = copy_all_before_char(fils_info->keyname_nai,
- roam_fils_params->username,
- '@',
- WMI_FILS_MAX_USERNAME_LENGTH);
-
- if (fils_info->key_nai_length <= usr_name_len) {
- sme_err("Fils info len error: key nai len %d, user name len %d",
- fils_info->key_nai_length, usr_name_len);
- return;
- }
-
- roam_fils_params->username_length = usr_name_len;
req_buffer->is_fils_connection = true;
+ roam_fils_params->username_length =
+ copy_all_before_char(fils_info->keyname_nai,
+ roam_fils_params->username, '@',
+ WMI_FILS_MAX_USERNAME_LENGTH);
roam_fils_params->next_erp_seq_num =
(fils_info->sequence_number + 1);
@@ -19758,6 +19958,22 @@
return QDF_STATUS_SUCCESS;
}
+ /* Roaming is not supported currently for OWE akm */
+ if (session->pCurRoamProfile &&
+ CSR_IS_AUTH_TYPE_OWE(
+ session->pCurRoamProfile->AuthType.authType[0])) {
+ sme_info("OWE Roaming not suppprted by fw");
+ return QDF_STATUS_SUCCESS;
+ }
+
+ /* Roaming is not supported currently for SAE authentication */
+ if (session->pCurRoamProfile &&
+ CSR_IS_AUTH_TYPE_SAE(
+ session->pCurRoamProfile->AuthType.authType[0])) {
+ sme_info("Roaming not supported for SAE connection");
+ return QDF_STATUS_SUCCESS;
+ }
+
/*
* The Dynamic Config Items Update may happen even if the state is in
* INIT. It is important to ensure that the command is passed down to
@@ -21763,6 +21979,9 @@
csr_roam_offload_scan(mac_ctx, session_id,
ROAM_SCAN_OFFLOAD_START,
REASON_CONNECT);
+ csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
+ eCSR_ROAM_SYNCH_COMPLETE,
+ eCSR_ROAM_RESULT_SUCCESS);
return status;
default:
sme_debug("LFR3: callback reason %d", reason);
@@ -21778,10 +21997,8 @@
return status;
}
conn_profile = &session->connectedProfile;
- csr_roam_stop_network(mac_ctx, session_id,
- session->pCurRoamProfile,
- bss_desc,
- ies_local);
+ csr_roam_stop_network(mac_ctx, session_id, session->pCurRoamProfile,
+ bss_desc, ies_local);
ps_global_info->remain_in_power_active_till_dhcp = false;
session->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
roam_info = qdf_mem_malloc(sizeof(tCsrRoamInfo));
@@ -21793,7 +22010,7 @@
return QDF_STATUS_E_NOMEM;
}
csr_scan_save_roam_offload_ap_to_scan_cache(mac_ctx, roam_synch_data,
- bss_desc);
+ bss_desc);
roam_info->sessionId = session_id;
csr_roam_call_callback(mac_ctx, roam_synch_data->roamedVdevId,
roam_info, 0, eCSR_ROAM_TDLS_STATUS_UPDATE,
diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h
index 802c90d..34b5f2c 100644
--- a/core/sme/src/csr/csr_inside_api.h
+++ b/core/sme/src/csr/csr_inside_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1282,4 +1282,18 @@
}
#endif
+/**
+ * csr_lookup_pmkid_using_bssid() - lookup pmkid using bssid
+ * @mac: pointer to mac
+ * @session: sme session pointer
+ * @pmk_cache: pointer to pmk cache
+ * @index: index value needs to be seached
+ *
+ * Return: true if pmkid is found else false
+ */
+bool csr_lookup_pmkid_using_bssid(tpAniSirGlobal mac,
+ tCsrRoamSession *session,
+ tPmkidCacheInfo *pmk_cache,
+ uint32_t *index);
+
#endif /* CSR_INSIDE_API_H__ */
diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c
index 4cb9eb4..a3f12e4 100644
--- a/core/sme/src/csr/csr_util.c
+++ b/core/sme/src/csr/csr_util.c
@@ -104,6 +104,31 @@
{0x00, 0x0F, 0xAC, 0x08},
/* AES GCMP-256 */
{0x00, 0x0F, 0xAC, 0x09},
+#ifdef WLAN_FEATURE_OWE
+#define ENUM_OWE 15
+ /* OWE https://tools.ietf.org/html/rfc8110 */
+ {0x00, 0x0F, 0xAC, 0x12},
+#else
+ {0x00, 0x00, 0x00, 0x00},
+#endif
+#define ENUM_SUITEB_EAP256 16
+ {0x00, 0x0F, 0xAC, 0x0B},
+#define ENUM_SUITEB_EAP384 17
+ {0x00, 0x0F, 0xAC, 0x0C},
+#ifdef WLAN_FEATURE_SAE
+#define ENUM_SAE 18
+ /* SAE */
+ {0x00, 0x0F, 0xAC, 0x08},
+#define ENUM_FT_SAE 19
+ /* FT SAE */
+ {0x00, 0x0F, 0xAC, 0x09},
+#else
+ {0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00},
+#endif
+#define ENUM_DPP_RSN 20
+ /* DPP RSN */
+ {0x50, 0x6F, 0x9A, 0x02},
/* define new oui here, update #define CSR_OUI_***_INDEX */
};
@@ -119,6 +144,16 @@
uint8_t csr_wme_info_oui[CSR_WME_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
uint8_t csr_wme_parm_oui[CSR_WME_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
+uint8_t csr_group_mgmt_oui[][CSR_RSN_OUI_SIZE] = {
+#define ENUM_CMAC 0
+ {0x00, 0x0F, 0xAC, 0x06},
+#define ENUM_GMAC_128 1
+ {0x00, 0x0F, 0xAC, 0x0B},
+#define ENUM_GMAC_256 2
+ {0x00, 0x0F, 0xAC, 0x0C},
+};
+
+
/* ////////////////////////////////////////////////////////////////////// */
/**
@@ -261,6 +296,7 @@
CASE_RETURN_STR(eCSR_ROAM_START);
CASE_RETURN_STR(eCSR_ROAM_ABORT);
CASE_RETURN_STR(eCSR_ROAM_NAPI_OFF);
+ CASE_RETURN_STR(eCSR_ROAM_SAE_COMPUTE);
default:
return "unknown";
}
@@ -1946,6 +1982,11 @@
case eCSR_AUTH_TYPE_FILS_SHA384:
case eCSR_AUTH_TYPE_FT_FILS_SHA256:
case eCSR_AUTH_TYPE_FT_FILS_SHA384:
+ case eCSR_AUTH_TYPE_OWE:
+ case eCSR_AUTH_TYPE_SUITEB_EAP_SHA256:
+ case eCSR_AUTH_TYPE_SUITEB_EAP_SHA384:
+ case eCSR_AUTH_TYPE_SAE:
+ case eCSR_AUTH_TYPE_DPP_RSN:
fRSNProfile = true;
break;
@@ -2709,6 +2750,95 @@
}
#endif
+#ifdef WLAN_FEATURE_OWE
+/*
+ * csr_is_auth_wpa_owe() - check whether oui is OWE
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is OWE, false otherwise
+ */
+static bool csr_is_auth_wpa_owe(tpAniSirGlobal mac,
+ uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+ uint8_t suite_count, uint8_t oui[])
+{
+ return csr_is_oui_match
+ (mac, all_suites, suite_count, csr_rsn_oui[ENUM_OWE], oui);
+}
+#endif
+
+/*
+ * csr_is_auth_suiteb_eap_256() - check whether oui is SuiteB EAP256
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is SuiteB EAP256, false otherwise
+ */
+static bool csr_is_auth_suiteb_eap_256(tpAniSirGlobal mac,
+ uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+ uint8_t suite_count, uint8_t oui[])
+{
+ return csr_is_oui_match(mac, all_suites, suite_count,
+ csr_rsn_oui[ENUM_SUITEB_EAP256], oui);
+}
+
+/*
+ * csr_is_auth_suiteb_eap_384() - check whether oui is SuiteB EAP384
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is SuiteB EAP384, false otherwise
+ */
+static bool csr_is_auth_suiteb_eap_384(tpAniSirGlobal mac,
+ uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+ uint8_t suite_count, uint8_t oui[])
+{
+ return csr_is_oui_match(mac, all_suites, suite_count,
+ csr_rsn_oui[ENUM_SUITEB_EAP384], oui);
+}
+
+#ifdef WLAN_FEATURE_SAE
+/*
+ * csr_is_auth_wpa_sae() - check whether oui is SAE
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is SAE, false otherwise
+ */
+static bool csr_is_auth_wpa_sae(tpAniSirGlobal mac,
+ uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+ uint8_t suite_count, uint8_t oui[])
+{
+ return csr_is_oui_match
+ (mac, all_suites, suite_count, csr_rsn_oui[ENUM_SAE], oui);
+}
+#endif
+
+/*
+ * csr_is_auth_dpp_rsn() - check whether oui is dpp rsn
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is dpp rsn, false otherwise
+ */
+static bool csr_is_auth_dpp_rsn(tpAniSirGlobal mac,
+ uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+ uint8_t suite_count, uint8_t oui[])
+{
+ return csr_is_oui_match(mac, all_suites, suite_count,
+ csr_rsn_oui[ENUM_DPP_RSN], oui);
+}
+
static bool csr_is_auth_wpa(tpAniSirGlobal pMac,
uint8_t AllSuites[][CSR_WPA_OUI_SIZE],
uint8_t cAllSuites, uint8_t Oui[])
@@ -2725,6 +2855,56 @@
(pMac, AllSuites, cAllSuites, csr_wpa_oui[02], Oui);
}
+#ifdef WLAN_FEATURE_GMAC
+/*
+ * csr_is_group_mgmt_gmac_128() - check whether oui is GMAC_128
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is GMAC_128, false otherwise
+ */
+static bool csr_is_group_mgmt_gmac_128(tpAniSirGlobal mac,
+ uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+ uint8_t suite_count, uint8_t oui[])
+{
+ return csr_is_oui_match(mac, all_suites, suite_count,
+ csr_group_mgmt_oui[ENUM_GMAC_128], oui);
+}
+
+/*
+ * csr_is_group_mgmt_gmac_256() - check whether oui is GMAC_256
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is GMAC_256, false otherwise
+ */
+static bool csr_is_group_mgmt_gmac_256(tpAniSirGlobal mac,
+ uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+ uint8_t suite_count, uint8_t oui[])
+{
+ return csr_is_oui_match(mac, all_suites, suite_count,
+ csr_group_mgmt_oui[ENUM_GMAC_256], oui);
+}
+#else
+static bool csr_is_group_mgmt_gmac_128(tpAniSirGlobal mac,
+ uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+ uint8_t suite_count, uint8_t oui[])
+{
+ return false;
+}
+
+static bool csr_is_group_mgmt_gmac_256(tpAniSirGlobal mac,
+ uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+ uint8_t suite_count, uint8_t oui[])
+{
+ return false;
+}
+#endif
+
static uint8_t csr_get_oui_index_from_cipher(eCsrEncryptionType enType)
{
uint8_t OUIIndex;
@@ -2825,6 +3005,78 @@
{
}
#endif
+
+#ifdef WLAN_FEATURE_OWE
+/**
+ * csr_check_n_set_owe_auth() - update negotiated auth if matches to OWE auth type
+ * @mac_ctx: pointer to mac context
+ * @authsuites: auth suites
+ * @c_auth_suites: auth suites count
+ * @authentication: authentication
+ * @auth_type: authentication type list
+ * @index: current counter
+ * @neg_authtype: pointer to negotiated auth
+ *
+ * Return: None
+ */
+static void csr_check_n_set_owe_auth(tpAniSirGlobal mac_ctx,
+ uint8_t authsuites[][CSR_RSN_OUI_SIZE], uint8_t c_auth_suites,
+ uint8_t authentication[], tCsrAuthList *auth_type,
+ uint8_t index, eCsrAuthType *neg_authtype)
+{
+ if ((*neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+ csr_is_auth_wpa_owe(mac_ctx, authsuites,
+ c_auth_suites, authentication)) {
+ if (eCSR_AUTH_TYPE_OWE == auth_type->authType[index])
+ *neg_authtype = eCSR_AUTH_TYPE_OWE;
+ }
+
+ sme_debug("negotiated auth type is %d", *neg_authtype);
+}
+#else
+static void csr_check_n_set_owe_auth(tpAniSirGlobal mac_ctx,
+ uint8_t authsuites[][CSR_RSN_OUI_SIZE], uint8_t c_auth_suites,
+ uint8_t authentication[], tCsrAuthList *auth_type,
+ uint8_t index, eCsrAuthType *neg_authtype)
+{
+}
+#endif
+
+#ifdef WLAN_FEATURE_SAE
+/**
+ * csr_check_sae_auth() - update negotiated auth if matches to SAE auth type
+ * @mac_ctx: pointer to mac context
+ * @authsuites: auth suites
+ * @c_auth_suites: auth suites count
+ * @authentication: authentication
+ * @auth_type: authentication type list
+ * @index: current counter
+ * @neg_authtype: pointer to negotiated auth
+ *
+ * Return: None
+ */
+static void csr_check_sae_auth(tpAniSirGlobal mac_ctx,
+ uint8_t authsuites[][CSR_RSN_OUI_SIZE], uint8_t c_auth_suites,
+ uint8_t authentication[], tCsrAuthList *auth_type,
+ uint8_t index, eCsrAuthType *neg_authtype)
+{
+ if ((*neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+ csr_is_auth_wpa_sae(mac_ctx, authsuites,
+ c_auth_suites, authentication)) {
+ if (eCSR_AUTH_TYPE_SAE == auth_type->authType[index])
+ *neg_authtype = eCSR_AUTH_TYPE_SAE;
+ }
+ sme_debug("negotiated auth type is %d", *neg_authtype);
+}
+#else
+static void csr_check_sae_auth(tpAniSirGlobal mac_ctx,
+ uint8_t authsuites[][CSR_RSN_OUI_SIZE], uint8_t c_auth_suites,
+ uint8_t authentication[], tCsrAuthList *auth_type,
+ uint8_t index, eCsrAuthType *neg_authtype)
+{
+}
+#endif
+
/**
* csr_get_rsn_information() - to get RSN infomation
* @hal: pointer to HAL
@@ -2838,6 +3090,8 @@
* @capabilities: RSN capabilities
* @negotiated_authtype: Negotiated auth type
* @negotiated_mccipher: negotiated multicast cipher
+ * @gp_mgmt_cipher: group management cipher
+ * @mgmt_encryption_type: group management encryption type
*
* This routine will get all RSN information
*
@@ -2850,18 +3104,24 @@
uint8_t *mcast_cipher, uint8_t *auth_suite,
tCsrRSNCapabilities *capabilities,
eCsrAuthType *negotiated_authtype,
- eCsrEncryptionType *negotiated_mccipher)
+ eCsrEncryptionType *negotiated_mccipher,
+ uint8_t *gp_mgmt_cipher,
+ tAniEdType *mgmt_encryption_type)
{
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
bool acceptable_cipher = false;
+ bool group_mgmt_acceptable_cipher = false;
uint8_t c_ucast_cipher = 0;
uint8_t c_mcast_cipher = 0;
+ uint8_t c_group_mgmt_cipher = 0;
uint8_t c_auth_suites = 0, i;
uint8_t unicast[CSR_RSN_OUI_SIZE];
uint8_t multicast[CSR_RSN_OUI_SIZE];
+ uint8_t group_mgmt[CSR_RSN_OUI_SIZE];
uint8_t authsuites[CSR_RSN_MAX_AUTH_SUITES][CSR_RSN_OUI_SIZE];
uint8_t authentication[CSR_RSN_OUI_SIZE];
uint8_t mccipher_arr[CSR_RSN_MAX_MULTICAST_CYPHERS][CSR_RSN_OUI_SIZE];
+ uint8_t group_mgmt_arr[CSR_RSN_MAX_MULTICAST_CYPHERS][CSR_RSN_OUI_SIZE];
eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
if (!rsn_ie->present)
@@ -2903,6 +3163,28 @@
if (negotiated_mccipher)
*negotiated_mccipher = mc_encryption->encryptionType[i];
+ /* Group Management Cipher only for 11w */
+ if (mgmt_encryption_type) {
+ c_group_mgmt_cipher++;
+ qdf_mem_copy(group_mgmt_arr, rsn_ie->gp_mgmt_cipher_suite,
+ CSR_RSN_OUI_SIZE);
+ if (csr_is_group_mgmt_gmac_128(mac_ctx, group_mgmt_arr,
+ c_group_mgmt_cipher, group_mgmt)) {
+ group_mgmt_acceptable_cipher = true;
+ *mgmt_encryption_type = eSIR_ED_AES_GMAC_128;
+ } else if (csr_is_group_mgmt_gmac_256(mac_ctx, group_mgmt_arr,
+ c_group_mgmt_cipher, group_mgmt)) {
+ group_mgmt_acceptable_cipher = true;
+ *mgmt_encryption_type = eSIR_ED_AES_GMAC_256;
+ } else {
+ /* Default is CMAC */
+ group_mgmt_acceptable_cipher = true;
+ *mgmt_encryption_type = eSIR_ED_AES_128_CMAC;
+ qdf_mem_copy(group_mgmt, csr_group_mgmt_oui[ENUM_CMAC],
+ CSR_RSN_OUI_SIZE);
+ }
+ }
+
/* Initializing with false as it has true value already */
acceptable_cipher = false;
for (i = 0; i < auth_type->numEntries; i++) {
@@ -2914,6 +3196,15 @@
csr_is_fils_auth(mac_ctx, authsuites, c_auth_suites,
authentication, auth_type, i, &neg_authtype);
/* Changed the AKM suites according to order of preference */
+ csr_check_sae_auth(mac_ctx, authsuites, c_auth_suites,
+ authentication, auth_type, i, &neg_authtype);
+
+ if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+ csr_is_auth_dpp_rsn(mac_ctx, authsuites,
+ c_auth_suites, authentication)) {
+ if (eCSR_AUTH_TYPE_DPP_RSN == auth_type->authType[i])
+ neg_authtype = eCSR_AUTH_TYPE_DPP_RSN;
+ }
if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
csr_is_ft_auth_rsn(mac_ctx, authsuites,
c_auth_suites, authentication)) {
@@ -2964,6 +3255,23 @@
neg_authtype = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
}
#endif
+ csr_check_n_set_owe_auth(mac_ctx, authsuites, c_auth_suites,
+ authentication, auth_type, i, &neg_authtype);
+
+ if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+ csr_is_auth_suiteb_eap_256(mac_ctx, authsuites,
+ c_auth_suites, authentication)) {
+ if (eCSR_AUTH_TYPE_SUITEB_EAP_SHA256 ==
+ auth_type->authType[i])
+ neg_authtype = eCSR_AUTH_TYPE_SUITEB_EAP_SHA256;
+ }
+ if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+ csr_is_auth_suiteb_eap_384(mac_ctx, authsuites,
+ c_auth_suites, authentication)) {
+ if (eCSR_AUTH_TYPE_SUITEB_EAP_SHA384 ==
+ auth_type->authType[i])
+ neg_authtype = eCSR_AUTH_TYPE_SUITEB_EAP_SHA384;
+ }
/*
* The 1st auth type in the APs RSN IE, to match stations
@@ -2985,6 +3293,10 @@
if (ucast_cipher)
qdf_mem_copy(ucast_cipher, unicast, CSR_RSN_OUI_SIZE);
+ if (gp_mgmt_cipher && group_mgmt_acceptable_cipher)
+ qdf_mem_copy(gp_mgmt_cipher, group_mgmt,
+ CSR_RSN_OUI_SIZE);
+
if (auth_suite)
qdf_mem_copy(auth_suite, authentication,
CSR_RSN_OUI_SIZE);
@@ -3113,7 +3425,7 @@
pEnMcType, &pIes->RSN,
NULL, NULL, NULL, NULL,
pNegotiatedAuthType,
- pNegotiatedMCCipher);
+ pNegotiatedMCCipher, NULL, NULL);
#ifdef WLAN_FEATURE_11W
/* If all the filter matches then finally checks for PMF capabilities */
if (fRSNMatch)
@@ -3166,16 +3478,7 @@
return false;
}
-/**
- * csr_lookup_pmkid_using_bssid() - lookup pmkid using bssid
- * @mac: pointer to mac
- * @session: sme session pointer
- * @pmk_cache: pointer to pmk cache
- * @index: index value needs to be seached
- *
- * Return: true if pmkid is found else false
- */
-static bool csr_lookup_pmkid_using_bssid(tpAniSirGlobal mac,
+bool csr_lookup_pmkid_using_bssid(tpAniSirGlobal mac,
tCsrRoamSession *session,
tPmkidCacheInfo *pmk_cache,
uint32_t *index)
@@ -3332,6 +3635,7 @@
uint8_t cbRSNIe = 0;
uint8_t UnicastCypher[CSR_RSN_OUI_SIZE];
uint8_t MulticastCypher[CSR_RSN_OUI_SIZE];
+ uint8_t gp_mgmt_cipher_suite[CSR_RSN_OUI_SIZE];
uint8_t AuthSuite[CSR_RSN_OUI_SIZE];
tCsrRSNAuthIe *pAuthSuite;
tCsrRSNCapabilities RSNCapabilities;
@@ -3383,7 +3687,9 @@
&pProfile->mcEncryptionType,
&pIesLocal->RSN, UnicastCypher,
MulticastCypher, AuthSuite,
- &RSNCapabilities, &negAuthType, NULL);
+ &RSNCapabilities, &negAuthType, NULL,
+ gp_mgmt_cipher_suite,
+ &pProfile->mgmt_encryption_type);
if (!fRSNMatch)
break;
@@ -3450,6 +3756,7 @@
} else {
pPMK->cPMKIDs = 0;
}
+ qdf_mem_zero(&pmkid_cache, sizeof(pmkid_cache));
#ifdef WLAN_FEATURE_11W
/* Advertise BIP in group cipher key management only if PMF is
@@ -3460,8 +3767,8 @@
pGroupMgmtCipherSuite =
(uint8_t *) pPMK + sizeof(uint16_t) +
(pPMK->cPMKIDs * CSR_RSN_PMKID_SIZE);
- qdf_mem_copy(pGroupMgmtCipherSuite, csr_rsn_oui[07],
- CSR_WPA_OUI_SIZE);
+ qdf_mem_copy(pGroupMgmtCipherSuite,
+ gp_mgmt_cipher_suite, CSR_RSN_OUI_SIZE);
}
#endif
@@ -4265,7 +4572,12 @@
case eCSR_ENCRYPT_TYPE_AES_GCMP_256:
edType = eSIR_ED_GCMP_256;
break;
-
+ case eCSR_ENCRYPT_TYPE_AES_GMAC_128:
+ edType = eSIR_ED_AES_GMAC_128;
+ break;
+ case eCSR_ENCRYPT_TYPE_AES_GMAC_256:
+ edType = eSIR_ED_AES_GMAC_256;
+ break;
#endif
}
diff --git a/core/sme/src/rrm/sme_rrm.c b/core/sme/src/rrm/sme_rrm.c
index 38b7560..8e7cba1 100644
--- a/core/sme/src/rrm/sme_rrm.c
+++ b/core/sme/src/rrm/sme_rrm.c
@@ -845,6 +845,14 @@
sme_debug("Received Beacon report request ind Channel = %d",
pBeaconReq->channelInfo.channelNum);
+
+ if (pBeaconReq->channelList.numChannels >
+ SIR_ESE_MAX_MEAS_IE_REQS) {
+ sme_err("Beacon report request numChannels:%u exceeds max num channels",
+ pBeaconReq->channelList.numChannels);
+ return QDF_STATUS_E_INVAL;
+ }
+
/* section 11.10.8.1 (IEEE Std 802.11k-2008) */
/* channel 0 and 255 has special meaning. */
if ((pBeaconReq->channelInfo.channelNum == 0) ||
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
index 34b6df1..47b6532 100644
--- a/core/wma/inc/wma.h
+++ b/core/wma/inc/wma.h
@@ -970,16 +970,18 @@
* @key_length: key length
* @key: key
* @key_id: key id
+ * @key_cipher: key cipher
*/
typedef struct {
uint16_t key_length;
- uint8_t key[CSR_AES_KEY_LEN];
+ uint8_t key[CSR_AES_GMAC_256_KEY_LEN];
/* IPN is maintained per iGTK keyID
* 0th index for iGTK keyID = 4;
* 1st index for iGTK KeyID = 5
*/
wma_igtk_ipn_t key_id[2];
+ uint32_t key_cipher;
} wma_igtk_key_t;
#endif
@@ -1048,6 +1050,7 @@
* @aid: association id
* @rmfEnabled: Robust Management Frame (RMF) enabled/disabled
* @key: GTK key
+ * @ucast_key_cipher: unicast cipher key
* @uapsd_cached_val: uapsd cached value
* @stats_rsp: stats response
* @fw_stats_set: fw stats value
@@ -1124,6 +1127,7 @@
uint8_t rmfEnabled;
#ifdef WLAN_FEATURE_11W
wma_igtk_key_t key;
+ uint32_t ucast_key_cipher;
#endif /* WLAN_FEATURE_11W */
uint32_t uapsd_cached_val;
tAniGetPEStatsRsp *stats_rsp;
diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c
index 6037f08..5b3e978 100644
--- a/core/wma/src/wma_data.c
+++ b/core/wma/src/wma_data.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -2580,6 +2580,37 @@
}
/**
+ * wma_is_rmf_mgmt_action_frame() - check RMF action frame by category
+ * @action_category: action frame actegory
+ *
+ * This function check the frame is robust mgmt action frame or not
+ *
+ * Return: true - if category is robust mgmt type
+ */
+static bool wma_is_rmf_mgmt_action_frame(uint8_t action_category)
+{
+ switch (action_category) {
+ case SIR_MAC_ACTION_SPECTRUM_MGMT:
+ case SIR_MAC_ACTION_QOS_MGMT:
+ case SIR_MAC_ACTION_DLP:
+ case SIR_MAC_ACTION_BLKACK:
+ case SIR_MAC_ACTION_RRM:
+ case SIR_MAC_ACTION_FAST_BSS_TRNST:
+ case SIR_MAC_ACTION_SA_QUERY:
+ case SIR_MAC_ACTION_PROT_DUAL_PUB:
+ case SIR_MAC_ACTION_WNM:
+ case SIR_MAC_ACITON_MESH:
+ case SIR_MAC_ACTION_MHF:
+ case SIR_MAC_ACTION_FST:
+ return true;
+ default:
+ break;
+ }
+ return false;
+
+}
+
+/**
* wma_tx_packet() - Sends Tx Frame to TxRx
* @wma_context: wma context
* @tx_frame: frame buffer
@@ -2620,6 +2651,8 @@
uint8_t *pFrame = NULL;
void *pPacket = NULL;
uint16_t newFrmLen = 0;
+ uint8_t action_category = 0;
+ bool deauth_disassoc = false;
#endif /* WLAN_FEATURE_11W */
struct wma_txrx_node *iface;
tpAniSirGlobal pMac;
@@ -2676,14 +2709,29 @@
pFc->subType == SIR_MAC_MGMT_ACTION)) {
struct ieee80211_frame *wh =
(struct ieee80211_frame *)qdf_nbuf_data(tx_frame);
+ if (pFc->subType == SIR_MAC_MGMT_ACTION)
+ action_category =
+ *((uint8_t *)(qdf_nbuf_data(tx_frame)) +
+ sizeof(struct ieee80211_frame));
+ else
+ deauth_disassoc = true;
if (!IEEE80211_IS_BROADCAST(wh->i_addr1) &&
!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
if (pFc->wep) {
+ uint8_t mic_len, hdr_len;
+
/* Allocate extra bytes for privacy header and
* trailer
*/
- newFrmLen = frmLen + IEEE80211_CCMP_HEADERLEN +
- IEEE80211_CCMP_MICLEN;
+ if (iface->ucast_key_cipher ==
+ WMI_CIPHER_AES_GCM) {
+ hdr_len = WLAN_IEEE80211_GCMP_HEADERLEN;
+ mic_len = WLAN_IEEE80211_GCMP_MICLEN;
+ } else {
+ hdr_len = IEEE80211_CCMP_HEADERLEN;
+ mic_len = IEEE80211_CCMP_MICLEN;
+ }
+ newFrmLen = frmLen + hdr_len + mic_len;
qdf_status =
cds_packet_alloc((uint16_t) newFrmLen,
(void **)&pFrame,
@@ -2706,7 +2754,7 @@
qdf_mem_set(pFrame, newFrmLen, 0);
qdf_mem_copy(pFrame, wh, sizeof(*wh));
qdf_mem_copy(pFrame + sizeof(*wh) +
- IEEE80211_CCMP_HEADERLEN,
+ hdr_len,
pData + sizeof(*wh),
frmLen - sizeof(*wh));
@@ -2717,7 +2765,8 @@
pFc = (tpSirMacFrameCtl)
(qdf_nbuf_data(tx_frame));
}
- } else {
+ } else if (deauth_disassoc ||
+ wma_is_rmf_mgmt_action_frame(action_category)) {
/* Allocate extra bytes for MMIE */
newFrmLen = frmLen + IEEE80211_MMIE_LEN;
qdf_status = cds_packet_alloc((uint16_t) newFrmLen,
diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c
index 41d6cd5..56d4542 100644
--- a/core/wma/src/wma_dev_if.c
+++ b/core/wma/src/wma_dev_if.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1881,6 +1881,17 @@
return status;
}
+#ifdef WLAN_FEATURE_11W
+static void wma_clear_iface_key(struct wma_txrx_node *iface)
+{
+ qdf_mem_zero(&iface->key, sizeof(iface->key));
+}
+#else
+static void wma_clear_iface_key(struct wma_txrx_node *iface)
+{
+}
+#endif
+
/**
* wma_vdev_stop_resp_handler() - vdev stop response handler
* @handle: wma handle
@@ -1922,6 +1933,18 @@
/* vdev in stopped state, no more waiting for key */
iface->is_waiting_for_key = false;
+ /*
+ * Reset the rmfEnabled as there might be MGMT action frames
+ * sent on this vdev before the next session is established.
+ */
+ if (iface->rmfEnabled) {
+ iface->rmfEnabled = 0;
+ WMA_LOGD(FL("Reset rmfEnabled for vdev %d"),
+ resp_event->vdev_id);
+ }
+
+ /* Clear key information */
+ wma_clear_iface_key(iface);
wma_release_wakelock(&iface->vdev_stop_wakelock);
req_msg = wma_find_vdev_req(wma, resp_event->vdev_id,
@@ -2037,6 +2060,7 @@
wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
}
+
free_req_msg:
qdf_mc_timer_destroy(&req_msg->event_timeout);
qdf_mem_free(req_msg);
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index 36081f1..9ae9646 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -11267,10 +11267,7 @@
if (wma == NULL)
return;
- if (!wma_is_vdev_valid(req->vdev_id)) {
- WMA_LOGE(FL("Invalid vdev id"));
- return;
- }
+
/* save the copy of the config params */
qdf_mem_copy(&wma->ss_configs, req, sizeof(*req));
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index b6c6d6c..fb546c0 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -847,8 +847,6 @@
&wma->interfaces[vdev_id];
bool prev_dtim_enabled;
uint32_t listen_interval;
- uint32_t beacon_interval_mod;
- uint32_t max_mod_dtim;
QDF_STATUS ret;
iface->alt_modulated_dtim = privcmd->param_value;
@@ -863,41 +861,22 @@
if ((true == iface->alt_modulated_dtim_enabled) ||
(true == prev_dtim_enabled)) {
- beacon_interval_mod = iface->beaconInterval / 100;
- if (!beacon_interval_mod)
- beacon_interval_mod = 1;
+ listen_interval = iface->alt_modulated_dtim
+ * iface->dtimPeriod;
- if (iface->dtimPeriod)
- max_mod_dtim = wma->staMaxLIModDtim
- / (iface->dtimPeriod*beacon_interval_mod);
- else
- max_mod_dtim = wma->staMaxLIModDtim/beacon_interval_mod;
-
- if (!max_mod_dtim)
- max_mod_dtim = 1;
-
- if (iface->alt_modulated_dtim > max_mod_dtim) {
- WMA_LOGE("User ModDtim(%d) exceeding ceiling limit(%d)",
- iface->alt_modulated_dtim, max_mod_dtim);
- listen_interval = max_mod_dtim * iface->dtimPeriod;
- } else {
- listen_interval = iface->alt_modulated_dtim
- * iface->dtimPeriod;
- }
-
- WMA_LOGD("Setting Listen Interval %d for vdev id %d",
- listen_interval, vdev_id);
- ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
- WMI_VDEV_PARAM_LISTEN_INTERVAL,
- listen_interval);
+ ret = wma_vdev_set_param(wma->wmi_handle,
+ privcmd->param_vdev_id,
+ WMI_VDEV_PARAM_LISTEN_INTERVAL,
+ listen_interval);
if (QDF_IS_STATUS_ERROR(ret))
/* Even if it fails, continue */
WMA_LOGW("Failed to set listen interval %d",
listen_interval);
- ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
- WMI_VDEV_PARAM_DTIM_POLICY,
- NORMAL_DTIM);
+ ret = wma_vdev_set_param(wma->wmi_handle,
+ privcmd->param_vdev_id,
+ WMI_VDEV_PARAM_DTIM_POLICY,
+ NORMAL_DTIM);
if (QDF_IS_STATUS_ERROR(ret))
WMA_LOGE("Failed to Set to Normal DTIM policy");
}
@@ -4841,7 +4820,6 @@
phy_caps = &wma_handle->phy_caps;
cfg->sar_version = phy_caps->sar_capability.active_version;
}
-
/**
* wma_update_hdd_cfg() - update HDD config
* @wma_handle: wma handle
@@ -7973,7 +7951,6 @@
case WMA_RESET_PASSPOINT_LIST_REQ:
wma_reset_passpoint_network_list(wma_handle,
(struct wifi_passpoint_req *)msg->bodyptr);
- qdf_mem_free(msg->bodyptr);
break;
#endif /* FEATURE_WLAN_EXTSCAN */
case WMA_SET_SCAN_MAC_OUI_REQ:
@@ -8327,8 +8304,10 @@
case SIR_HAL_SET_DEL_PMKID_CACHE:
wma_set_del_pmkid_cache(wma_handle,
(wmi_pmk_cache *) msg->bodyptr, msg->reserved);
- if (msg->bodyptr)
+ if (msg->bodyptr) {
+ qdf_mem_zero(msg->bodyptr, sizeof(wmi_pmk_cache));
qdf_mem_free(msg->bodyptr);
+ }
break;
case SIR_HAL_HLP_IE_INFO:
wma_roam_scan_send_hlp(wma_handle,
diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c
index 92ba9fe..5e61e62 100644
--- a/core/wma/src/wma_mgmt.c
+++ b/core/wma/src/wma_mgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -72,6 +72,7 @@
#include <cdp_txrx_cfg.h>
#include <cdp_txrx_cmn.h>
#include <cdp_txrx_misc.h>
+#include <qdf_crypto.h>
/**
* wma_send_bcn_buf_ll() - prepare and send beacon buffer to fw for LL
@@ -1566,9 +1567,7 @@
{
struct set_key_params params;
QDF_STATUS status = QDF_STATUS_SUCCESS;
-#ifdef WLAN_FEATURE_11W
struct wma_txrx_node *iface = NULL;
-#endif /* WLAN_FEATURE_11W */
if ((key_params->key_type == eSIR_ED_NONE &&
key_params->key_len) || (key_params->key_type != eSIR_ED_NONE &&
!key_params->key_len)) {
@@ -1670,6 +1669,10 @@
case eSIR_ED_AES_128_CMAC:
params.key_cipher = WMI_CIPHER_AES_CMAC;
break;
+ case eSIR_ED_AES_GMAC_128:
+ case eSIR_ED_AES_GMAC_256:
+ params.key_cipher = WMI_CIPHER_AES_GMAC;
+ break;
#endif /* WLAN_FEATURE_11W */
/* Firmware uses length to detect GCMP 128/256*/
case eSIR_ED_GCMP:
@@ -1711,10 +1714,14 @@
params.key_len = key_params->key_len;
#ifdef WLAN_FEATURE_11W
- if (key_params->key_type == eSIR_ED_AES_128_CMAC) {
- iface = &wma_handle->interfaces[key_params->vdev_id];
+ iface = &wma_handle->interfaces[key_params->vdev_id];
+
+ if ((key_params->key_type == eSIR_ED_AES_128_CMAC) ||
+ (key_params->key_type == eSIR_ED_AES_GMAC_128) ||
+ (key_params->key_type == eSIR_ED_AES_GMAC_256)) {
if (iface) {
iface->key.key_length = key_params->key_len;
+ iface->key.key_cipher = params.key_cipher;
qdf_mem_copy(iface->key.key,
(const void *)key_params->key_data,
iface->key.key_length);
@@ -1725,6 +1732,9 @@
CMAC_IPN_LEN);
}
}
+
+ if (key_params->unicast && iface)
+ iface->ucast_key_cipher = params.key_cipher;
#endif /* WLAN_FEATURE_11W */
WMA_LOGD("Key setup : vdev_id %d key_idx %d key_type %d key_len %d",
@@ -1748,6 +1758,7 @@
if (iface)
iface->is_waiting_for_key = false;
+ qdf_mem_zero(¶ms, sizeof(struct set_key_params));
return status;
}
@@ -1874,6 +1885,8 @@
/* TODO: Should we wait till we get HTT_T2H_MSG_TYPE_SEC_IND? */
key_info->status = QDF_STATUS_SUCCESS;
+ qdf_mem_zero(&key_params, sizeof(struct wma_set_key_params));
+
out:
wma_send_msg_high_priority(wma_handle,
WMA_SET_BSSKEY_RSP, (void *)key_info, 0);
@@ -2164,6 +2177,7 @@
key_params.key_len = key_info->key[i].keyLength;
status = wma_setup_install_key_cmd(wma_handle, &key_params,
opmode);
+ qdf_mem_zero(&key_params, sizeof(struct wma_set_key_params));
if (status == QDF_STATUS_E_NOMEM) {
WMA_LOGE("%s:Failed to setup install key buf",
__func__);
@@ -3256,32 +3270,79 @@
uint8_t *efrm;
efrm = qdf_nbuf_data(wbuf) + qdf_nbuf_len(wbuf);
- key_id = (uint16_t)*(efrm - cds_get_mmie_size() + 2);
+
+ if (iface->key.key_cipher == WMI_CIPHER_AES_CMAC) {
+ key_id = (uint16_t)*(efrm - cds_get_mmie_size() + 2);
+ } else if (iface->key.key_cipher == WMI_CIPHER_AES_GMAC) {
+ key_id = (uint16_t)*(efrm - cds_get_gmac_mmie_size() + 2);
+ } else {
+ WMA_LOGE(FL("Invalid key cipher %d"), iface->key.key_cipher);
+ return -EINVAL;
+ }
if (!((key_id == WMA_IGTK_KEY_INDEX_4)
|| (key_id == WMA_IGTK_KEY_INDEX_5))) {
WMA_LOGE(FL("Invalid KeyID(%d) dropping the frame"), key_id);
return -EINVAL;
}
- if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
- WMI_SERVICE_STA_PMF_OFFLOAD)) {
- /*
- * if 11w offload is enabled then mmie validation is performed
- * in firmware, host just need to trim the mmie.
- */
- qdf_nbuf_trim_tail(wbuf, cds_get_mmie_size());
- } else {
- if (cds_is_mmie_valid(iface->key.key,
- iface->key.key_id[key_id - WMA_IGTK_KEY_INDEX_4].ipn,
- (uint8_t *) wh, efrm)) {
- WMA_LOGE(FL("Protected BC/MC frame MMIE validation successful"));
- /* Remove MMIE */
+
+ WMA_LOGD(FL("key_cipher %d key_id %d"), iface->key.key_cipher, key_id);
+
+ switch (iface->key.key_cipher) {
+ case WMI_CIPHER_AES_CMAC:
+ if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
+ WMI_SERVICE_STA_PMF_OFFLOAD)) {
+ /*
+ * if 11w offload is enabled then mmie validation is
+ * performed in firmware, host just need to trim the
+ * mmie.
+ */
qdf_nbuf_trim_tail(wbuf, cds_get_mmie_size());
} else {
- WMA_LOGE(FL("BC/MC MIC error or MMIE not present, dropping the frame"));
- return -EINVAL;
+ if (cds_is_mmie_valid(iface->key.key,
+ iface->key.key_id[key_id - WMA_IGTK_KEY_INDEX_4].ipn,
+ (uint8_t *) wh, efrm)) {
+ WMA_LOGD(FL("Protected BC/MC frame MMIE validation successful"));
+ /* Remove MMIE */
+ qdf_nbuf_trim_tail(wbuf, cds_get_mmie_size());
+ } else {
+ WMA_LOGD(FL("BC/MC MIC error or MMIE not present, dropping the frame"));
+ return -EINVAL;
+ }
}
+ break;
+
+ case WMI_CIPHER_AES_GMAC:
+ if (WMI_SERVICE_EXT_IS_ENABLED(wma_handle->wmi_service_bitmap,
+ wma_handle->wmi_service_ext_bitmap,
+ WMI_SERVICE_GMAC_OFFLOAD_SUPPORT)) {
+ /*
+ * if gmac offload is enabled then mmie validation is
+ * performed in firmware, host just need to trim the
+ * mmie.
+ */
+ WMA_LOGD(FL("Trim GMAC MMIE"));
+ qdf_nbuf_trim_tail(wbuf, cds_get_gmac_mmie_size());
+ } else {
+ if (cds_is_gmac_mmie_valid(iface->key.key,
+ iface->key.key_id[key_id - WMA_IGTK_KEY_INDEX_4].ipn,
+ (uint8_t *) wh, efrm, iface->key.key_length)) {
+ WMA_LOGD(FL("Protected BC/MC frame GMAC MMIE validation successful"));
+ /* Remove MMIE */
+ qdf_nbuf_trim_tail(wbuf,
+ cds_get_gmac_mmie_size());
+ } else {
+ WMA_LOGD(FL("BC/MC GMAC MIC error or MMIE not present, dropping the frame"));
+ return -EINVAL;
+ }
+ }
+ break;
+
+ default:
+ WMA_LOGE(FL("Unsupported key cipher %d"),
+ iface->key.key_cipher);
}
+
return 0;
}
@@ -3304,6 +3365,7 @@
{
uint8_t *orig_hdr;
uint8_t *ccmp;
+ uint8_t mic_len, hdr_len;
if ((wh)->i_fc[1] & IEEE80211_FC1_WEP) {
if (IEEE80211_IS_BROADCAST(wh->i_addr1) ||
@@ -3330,15 +3392,22 @@
return -EINVAL;
}
+ if (iface->ucast_key_cipher == WMI_CIPHER_AES_GCM) {
+ hdr_len = WLAN_IEEE80211_GCMP_HEADERLEN;
+ mic_len = WLAN_IEEE80211_GCMP_MICLEN;
+ } else {
+ hdr_len = IEEE80211_CCMP_HEADERLEN;
+ mic_len = IEEE80211_CCMP_MICLEN;
+ }
/* Strip privacy headers (and trailer)
* for a received frame
*/
qdf_mem_move(orig_hdr +
- IEEE80211_CCMP_HEADERLEN, wh,
+ hdr_len, wh,
sizeof(*wh));
qdf_nbuf_pull_head(wbuf,
- IEEE80211_CCMP_HEADERLEN);
- qdf_nbuf_trim_tail(wbuf, IEEE80211_CCMP_MICLEN);
+ hdr_len);
+ qdf_nbuf_trim_tail(wbuf, mic_len);
/*
* CCMP header has been pulled off
* reinitialize the start pointer of mac header
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index aa03345..d03eb5b 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -988,11 +988,12 @@
status = wmi_unified_roam_scan_offload_mode_cmd(wma_handle->wmi_handle,
scan_cmd_fp, params);
+ qdf_mem_zero(params, sizeof(struct roam_offload_scan_params));
+ qdf_mem_free(params);
if (QDF_IS_STATUS_ERROR(status))
return status;
WMA_LOGD("%s: WMA --> WMI_ROAM_SCAN_MODE", __func__);
- qdf_mem_free(params);
return status;
}
@@ -1344,6 +1345,10 @@
return WMI_AUTH_RSNA_FILS_SHA256;
case eCSR_AUTH_TYPE_FILS_SHA384:
return WMI_AUTH_RSNA_FILS_SHA384;
+ case eCSR_AUTH_TYPE_SUITEB_EAP_SHA256:
+ return WMI_AUTH_RSNA_SUITE_B_8021X_SHA256;
+ case eCSR_AUTH_TYPE_SUITEB_EAP_SHA384:
+ return WMI_AUTH_RSNA_SUITE_B_8021X_SHA384;
default:
return WMI_AUTH_NONE;
}
@@ -2048,6 +2053,7 @@
if (NULL == pMac) {
WMA_LOGE("%s: pMac is NULL", __func__);
+ qdf_mem_zero(roam_req, sizeof(tSirRoamOffloadScanReq));
qdf_mem_free(roam_req);
return QDF_STATUS_E_FAILURE;
}
@@ -2056,6 +2062,7 @@
/* roam scan offload is not enabled in firmware.
* Cannot initialize it in the middle of connection.
*/
+ qdf_mem_zero(roam_req, sizeof(tSirRoamOffloadScanReq));
qdf_mem_free(roam_req);
return QDF_STATUS_E_PERM;
}
@@ -2418,6 +2425,7 @@
default:
break;
}
+ qdf_mem_zero(roam_req, sizeof(tSirRoamOffloadScanReq));
qdf_mem_free(roam_req);
return qdf_status;
}
@@ -5367,14 +5375,12 @@
src_rssi[count++];
}
}
- dest_ap = (tSirWifiSignificantChange *)((char *)dest_ap +
- dest_ap->numOfRssi * sizeof(int32_t) +
- sizeof(*dest_ap));
+ dest_ap += dest_ap->numOfRssi * sizeof(int32_t);
src_chglist++;
}
dest_chglist->requestId = event->request_id;
dest_chglist->moreData = moredata;
- dest_chglist->numResults = numap;
+ dest_chglist->numResults = event->total_entries;
pMac->sme.pExtScanIndCb(pMac->hHdd,
eSIR_EXTSCAN_SIGNIFICANT_WIFI_CHANGE_RESULTS_IND,
diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c
index 2869e6a..02eea17 100644
--- a/core/wma/src/wma_utils.c
+++ b/core/wma/src/wma_utils.c
@@ -6331,23 +6331,23 @@
&res);
/* vdev_id can be invalid though status is success, hence validate */
- if (vdev_id >= wma_handle->max_bssid) {
+ if (vdev_id >= wma_handle->max_bssid) {
WMA_LOGE(FL("Received invalid vdev_id: %d"), vdev_id);
ret = -EINVAL;
goto free_res;
- }
+ }
/* Get interface for valid vdev_id */
- iface = &wma_handle->interfaces[vdev_id];
+ iface = &wma_handle->interfaces[vdev_id];
if (!iface) {
WMI_LOGE(FL("Interface not available for vdev_id: %d"),
vdev_id);
ret = -EINVAL;
goto free_res;
- }
+ }
- roam_scan_stats_req = iface->roam_scan_stats_req;
- iface->roam_scan_stats_req = NULL;
+ roam_scan_stats_req = iface->roam_scan_stats_req;
+ iface->roam_scan_stats_req = NULL;
if (!roam_scan_stats_req) {
WMI_LOGE(FL("No pending request vdev_id: %d"), vdev_id);
ret = -EINVAL;
@@ -6365,12 +6365,12 @@
(roam_scan_stats_req->cb)(roam_scan_stats_req->context, res);
free_roam_scan_stats_req:
- qdf_mem_free(roam_scan_stats_req);
+ qdf_mem_free(roam_scan_stats_req);
roam_scan_stats_req = NULL;
free_res:
- qdf_mem_free(res);
- res = NULL;
+ qdf_mem_free(res);
+ res = NULL;
return ret;
}