diff options
27 files changed, 920 insertions, 47 deletions
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index 122a6aec9476..638c203f6fd7 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -149,6 +149,56 @@ static eHalStatus hdd_RoamSetKeyCompleteHandler( hdd_adapter_t *pAdapter, eRoamCmdStatus roamStatus, eCsrRoamResult roamResult ); +#if defined(WLAN_FEATURE_SAE) && \ + defined(CFG80211_EXTERNAL_AUTH_SUPPORT) +/** + * 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 = WLAN_HDD_GET_CTX(adapter); + 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) { + hddLog(LOGE, FL("SAE info in NULL")); + return; + } + + flags = vos_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; + vos_mem_copy(params.bssid, sae_info->peer_mac_addr.bytes, + VOS_MAC_ADDR_SIZE); + vos_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); + hddLog(LOG1, FL("SAE: sent cmd")); +} +#else +static void wlan_hdd_sae_callback(hdd_adapter_t *adapter, + tCsrRoamInfo *roam_info) +{ } +#endif + static v_VOID_t hdd_connSetAuthenticated(hdd_adapter_t *pAdapter, v_U8_t authState) { @@ -4977,6 +5027,10 @@ hdd_smeRoamCallback(void *pContext, tCsrRoamInfo *pRoamInfo, tANI_U32 roamId, hdd_ndp_event_handler(pAdapter, pRoamInfo, roamId, roamStatus, roamResult ); break; + case eCSR_ROAM_SAE_COMPUTE: + if (pRoamInfo) + wlan_hdd_sae_callback(pAdapter, pRoamInfo); + break; case eCSR_ROAM_STA_CHANNEL_SWITCH: { pHddCtx = WLAN_HDD_GET_CTX(pAdapter); diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index 4cf47b1c8327..388a7517b109 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -440,6 +440,7 @@ wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = { .tx = 0xffff, .rx = BIT(SIR_MAC_MGMT_ACTION) | BIT(SIR_MAC_MGMT_TIME_ADVERT) | + BIT(SIR_MAC_MGMT_AUTH) | BIT(SIR_MAC_MGMT_PROBE_REQ), }, [NL80211_IFTYPE_AP] = { @@ -16194,7 +16195,8 @@ hdd_wiphy_set_max_sched_scans(struct wiphy *wiphy, uint8_t max_scans) } #endif /* KERNEL_VERSION(4, 12, 0) */ -#ifdef WLAN_FEATURE_SAE +#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 @@ -28404,6 +28406,65 @@ static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, } #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_context_t *hdd_ctx = wiphy_priv(wiphy); + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + int ret; + + if (hdd_get_conparam() == VOS_FTM_MODE) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Command not allowed in FTM mode")); + return -EPERM; + } + + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret) + return ret; + + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("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; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_external_auth(wiphy, dev, params); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif + #if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211) static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy, @@ -33031,4 +33092,8 @@ static struct cfg80211_ops wlan_hdd_cfg80211_ops = defined(CFG80211_ABORT_SCAN) .abort_scan = wlan_hdd_cfg80211_abort_scan, #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_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c index f5e15970cfb9..ed5277d8ba17 100644 --- a/CORE/HDD/src/wlan_hdd_p2p.c +++ b/CORE/HDD/src/wlan_hdd_p2p.c @@ -1973,6 +1973,7 @@ int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, uint8_t home_ch = 0; bool enb_random_mac = false; uint32_t mgmt_hdr_len = sizeof(struct ieee80211_hdr_3addr); + eHalStatus hal_status; ENTER(); @@ -2001,6 +2002,22 @@ int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, hdd_device_mode_to_string(pAdapter->device_mode), pAdapter->device_mode, type); + /* When frame to be transmitted is auth mgmt, then trigger + * sme_send_mgmt_tx to send auth frame without need for policy manager. + * Where as wlan_cfg80211_mgmt_tx requires roc and requires approval + * from policy manager + */ + if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) && + (type == SIR_MAC_MGMT_FRAME && + subType == SIR_MAC_MGMT_AUTH)) { + hal_status = sme_send_mgmt_tx(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, buf, len); + if (HAL_STATUS_SUCCESS(hal_status)) + return 0; + else + return -EINVAL; + } + if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_ACTION && len > IEEE80211_MIN_ACTION_SIZE) hddLog(LOG1, FL("category: %d, actionID: %d"), diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h index 6a0a9016da68..cf78093490f5 100644 --- a/CORE/MAC/inc/aniGlobal.h +++ b/CORE/MAC/inc/aniGlobal.h @@ -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. * @@ -411,6 +411,9 @@ typedef struct sLimTimers */ TX_TIMER gLimActiveToPassiveChannelTimer; + /* SAE authentication related timer */ + TX_TIMER sae_auth_timer; + //********************TIMER SECTION ENDS************************************************** // ALL THE FIELDS BELOW THIS CAN BE ZEROED OUT in limInitialize //**************************************************************************************** diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index 859cec802ae3..bc894d9810d7 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -1211,6 +1211,7 @@ typedef struct sSirSmeJoinReq #ifdef WLAN_FEATURE_FILS_SK struct cds_fils_connection_info fils_con_info; #endif + bool sae_pmk_cached; tSirBssDescription bssDescription; /* * WARNING: Pls make bssDescription as last variable in struct @@ -8685,4 +8686,33 @@ struct action_frame_random_filter { uint8_t mac_addr[VOS_MAC_ADDR_SIZE]; }; +/** + * 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; + v_MACADDR_t 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/wniApi.h b/CORE/MAC/inc/wniApi.h index 1c2a1fc4ac98..3c557520f454 100644 --- a/CORE/MAC/inc/wniApi.h +++ b/CORE/MAC/inc/wniApi.h @@ -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. * @@ -432,6 +432,9 @@ enum eWniMsgTypes /* Link layer statistics */ eWMI_SME_LL_STATS_IND, + 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/include/sirParams.h b/CORE/MAC/src/include/sirParams.h index 2778b57d32fc..67eb0eab64c4 100644 --- a/CORE/MAC/src/include/sirParams.h +++ b/CORE/MAC/src/include/sirParams.h @@ -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. * @@ -211,6 +211,19 @@ typedef struct sSirMbMsgP2p tANI_U32 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; +}; /* ******************************************* * * * @@ -898,6 +911,7 @@ typedef struct sSirMbMsgP2p #define SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE (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) diff --git a/CORE/MAC/src/pe/include/limGlobal.h b/CORE/MAC/src/pe/include/limGlobal.h index 5adc4f15bc00..c1ab4982d7d9 100644 --- a/CORE/MAC/src/pe/include/limGlobal.h +++ b/CORE/MAC/src/pe/include/limGlobal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, 2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -175,6 +175,7 @@ typedef enum eLimMlmStates eLIM_MLM_WT_FT_REASSOC_RSP_STATE, #endif eLIM_MLM_P2P_LISTEN_STATE, + eLIM_MLM_WT_SAE_AUTH_STATE, } tLimMlmStates; // 11h channel quiet states diff --git a/CORE/MAC/src/pe/include/limSession.h b/CORE/MAC/src/pe/include/limSession.h index a187b49cb192..1e2108e9d1d4 100644 --- a/CORE/MAC/src/pe/include/limSession.h +++ b/CORE/MAC/src/pe/include/limSession.h @@ -533,6 +533,7 @@ typedef struct sPESession // Added to Support BT-AMP uint8_t disassocmsgcnt; /* previous auth frame's sequence number */ uint16_t prev_auth_seq_num; + bool sae_pmk_cached; } tPESession, *tpPESession; /*------------------------------------------------------------------------- diff --git a/CORE/MAC/src/pe/lim/limProcessAuthFrame.c b/CORE/MAC/src/pe/lim/limProcessAuthFrame.c index ec6098909447..8c4267172771 100644 --- a/CORE/MAC/src/pe/lim/limProcessAuthFrame.c +++ b/CORE/MAC/src/pe/lim/limProcessAuthFrame.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. * @@ -105,6 +105,46 @@ isAuthValid(tpAniSirGlobal pMac, tpSirMacAuthFrameBody auth, return valid; } +#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 = WDA_GET_RX_MAC_HEADER(rx_pkt_info); + body_ptr = WDA_GET_RX_MPDU_DATA(rx_pkt_info); + frame_len = WDA_GET_RX_PAYLOAD_LEN(rx_pkt_info); + + limLog(mac_ctx, LOG1, + FL("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) + limLog(mac_ctx, LOGE, + FL("received SAE auth response in unexpected state %x"), + pe_session->limMlmState); + + limSendSmeMgmtFrameInd(mac_ctx, mac_hdr->fc.subType, + (uint8_t *) mac_hdr, + frame_len + sizeof(tSirMacMgmtHdr), 0, + WDA_GET_RX_CH(rx_pkt_info), pe_session, + WDA_GET_RX_RSSI_NORMALIZED(rx_pkt_info)); +} +#else +static void lim_process_sae_auth_frame(tpAniSirGlobal mac_ctx, + uint8_t *rx_pkt_info, tpPESession pe_session) +{} +#endif /** * limProcessAuthFrame @@ -165,6 +205,7 @@ limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession pse tpDphHashNode pStaDs = NULL; tANI_U16 assocId = 0; tANI_U16 currSeqNum = 0; + tANI_U16 auth_alg = 0; // Get pointer to Authentication frame header and body pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); @@ -219,6 +260,8 @@ limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession pse pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + auth_alg = *(uint16_t *)pBody; + limLog(pMac, LOG1, FL("auth_alg %d "), auth_alg); //Restore default failure timeout if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona && psessionEntry->defaultAuthFailureTimeout) { @@ -590,6 +633,10 @@ limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession pse eSIR_FALSE); goto free; } // else if (wlan_cfgGetInt(CFG_PRIVACY_OPTION_IMPLEMENTED)) + } else if ((auth_alg == + eSIR_AUTH_TYPE_SAE) && (LIM_IS_STA_ROLE(psessionEntry))) { + lim_process_sae_auth_frame(pMac, pRxPacketInfo, psessionEntry); + goto free; } // if (fc.wep) else { @@ -1179,17 +1226,29 @@ limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession pse if (pRxAuthFrameBody->authAlgoNumber != pMac->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 ((pMac->lim.gpLimMlmAuthReq->authType == + eSIR_AUTH_TYPE_SAE) && psessionEntry->sae_pmk_cached) { + limLog(pMac, LOGW, + FL("rx Auth frame2 auth algo %d in SAE PMK case"), + pRxAuthFrameBody->authAlgoNumber); + } else { + /** + * Received Authentication frame with an auth + * algorithm other than one requested. + * Wait until Authentication Failure Timeout. + */ - // Log error - PELOGW(limLog(pMac, LOGW, - FL("received Auth frame2 for unexpected auth algo number %d " - MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber, - MAC_ADDR_ARRAY(pHdr->sa));) + // Log error + PELOGW(limLog(pMac, LOGW, + FL("received Auth frame2 for unexpected auth algo number %d" + MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + } break; } diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c index c44899f18480..56c7340b71bf 100644 --- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c +++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.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. * @@ -73,10 +73,77 @@ #include "vos_packet.h" #include "vos_memory.h" #include "nan_datapath.h" +#include "limSecurityUtils.h" +#include "ieee80211_common.h" #define CHECK_BIT(value, mask) ((value) & (1 << (mask))) void limLogSessionStates(tpAniSirGlobal pMac); +#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) { + limLog(mac, LOGE, FL("SAE msg is NULL")); + return; + } + + session = pe_find_session_by_sme_session_id(mac, + sae_msg->session_id); + if (session == NULL) { + limLog(mac, LOGE, FL("SAE:Unable to find session")); + return; + } + + if (session->pePersona != VOS_STA_MODE) { + limLog(mac, LOGE, FL("SAE:Not supported in this mode %d"), + session->pePersona); + return; + } + + limLog(mac, LOG1, FL("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)) + limDeactivateAndChangeTimer(mac, + eLIM_AUTH_SAE_TIMER); + /* success */ + if (sae_msg->sae_status == IEEE80211_STATUS_SUCCESS) + limRestoreFromAuthState(mac, + eSIR_SME_SUCCESS, + eSIR_MAC_SUCCESS_STATUS, + session); + else + limRestoreFromAuthState(mac, + eSIR_SME_AUTH_REFUSED, + eSIR_MAC_UNSPEC_FAILURE_STATUS, + session); + break; + default: + /* SAE msg is received in unexpected state */ + limLog(mac, LOGE, FL("received SAE msg in state %X"), + session->limMlmState); + limPrintMlmState(mac, LOGE, session->limMlmState); + break; + } +} +#else +static void lim_process_sae_msg(tpAniSirGlobal mac, struct sir_sae_msg *body) +{} +#endif + /** ------------------------------------------------------------- \fn defMsgDecision \brief The function decides whether to defer a message or not in limProcessMessage function @@ -1513,7 +1580,11 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) limMsg->bodyptr = NULL; break; } - + case eWNI_SME_SEND_MGMT_FRAME_TX: + lim_send_mgmt_frame_tx(pMac, limMsg); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; case SIR_HAL_P2P_NOA_START_IND: { tpPESession psessionEntry = &pMac->lim.gpSession[0]; @@ -1750,6 +1821,7 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) 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 limProcessMlmReqMessages(pMac, @@ -2232,6 +2304,11 @@ send_link_resp: case SIR_HAL_NDP_END_IND: lim_handle_ndp_event_message(pMac, limMsg); break; + case eWNI_SME_SEND_SAE_MSG: + lim_process_sae_msg(pMac, limMsg->bodyptr); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; default: vos_mem_free((v_VOID_t*)limMsg->bodyptr); limMsg->bodyptr = NULL; diff --git a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c index 6e90b4d2c241..a0a2712c9aa9 100644 --- a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.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. * @@ -92,6 +92,51 @@ limSetChannel(tpAniSirGlobal pMac, tANI_U8 channel, tANI_U8 secChannelOffset, tP #define IS_MLM_SCAN_REQ_BACKGROUND_SCAN_NORMAL(pMac) (pMac->lim.gpLimMlmScanReq->backgroundScanMode == eSIR_NORMAL_BACKGROUND_SCAN) /** + * 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 = peFindSessionBySessionId(mac_ctx, + mac_ctx->lim.limTimers.sae_auth_timer.sessionId); + if (session == NULL) { + limLog(mac_ctx, LOGE, + FL("Session does not exist for given session id")); + return; + } + + limLog(mac_ctx, LOG1, + FL("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 == VOS_STA_MODE) + limRestoreFromAuthState(mac_ctx, + eSIR_SME_AUTH_TIMEOUT_RESULT_CODE, + eSIR_MAC_UNSPEC_FAILURE_REASON, session); + break; + default: + /* SAE authentication is timed out in unexpected state */ + limLog(mac_ctx, LOGE, + FL("received unexpected SAE auth timeout in state %X"), + session->limMlmState); + limPrintMlmState(mac_ctx, LOGE, session->limMlmState); + break; + } +} + +/** * limProcessMlmReqMessages() * *FUNCTION: @@ -159,6 +204,9 @@ limProcessMlmReqMessages(tpAniSirGlobal pMac, tpSirMsgQ Msg) break; case SIR_LIM_DISASSOC_ACK_TIMEOUT: limProcessDisassocAckTimeout(pMac); break; case SIR_LIM_DEAUTH_ACK_TIMEOUT: limProcessDeauthAckTimeout(pMac); break; + case SIR_LIM_AUTH_SAE_TIMEOUT: + lim_process_sae_auth_timeout(pMac); + break; case LIM_MLM_TSPEC_REQ: default: break; @@ -708,9 +756,15 @@ void limDoSendAuthMgmtFrame(tpAniSirGlobal pMac, tpPESession psessionEntry) { tSirMacAuthFrameBody authFrameBody; - //Prepare & send Authentication frame - authFrameBody.authAlgoNumber = + /* Mark auth algo as open when auth type is SAE and PMK is cached */ + if ((pMac->lim.gpLimMlmAuthReq->authType == eSIR_AUTH_TYPE_SAE) && + psessionEntry->sae_pmk_cached) { + authFrameBody.authAlgoNumber = eSIR_OPEN_SYSTEM; + } else { + authFrameBody.authAlgoNumber = (tANI_U8) pMac->lim.gpLimMlmAuthReq->authType; + } + //Prepare & send Authentication frame authFrameBody.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1; authFrameBody.authStatusCode = 0; pMac->auth_ack_status = LIM_AUTH_ACK_NOT_RCD; @@ -2269,7 +2323,86 @@ error: } /*** limProcessMlmJoinReq() ***/ +#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: tSirRetStatus + */ +static VOS_STATUS lim_process_mlm_auth_req_sae(tpAniSirGlobal mac_ctx, + tpPESession session) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + struct sir_sae_info *sae_info; + vos_msg_t msg; + + sae_info = vos_mem_malloc(sizeof(*sae_info)); + if (sae_info == NULL) { + limLog(mac_ctx, LOGP, FL("Memory allocation failed")); + return VOS_STATUS_E_FAILURE; + } + + sae_info->msg_type = eWNI_SME_TRIGGER_SAE; + sae_info->msg_len = sizeof(*sae_info); + sae_info->vdev_id = session->smeSessionId; + + vos_mem_copy(sae_info->peer_mac_addr.bytes, + session->bssId, + VOS_MAC_ADDR_SIZE); + + sae_info->ssid.length = session->ssId.length; + vos_mem_copy(sae_info->ssid.ssId, + session->ssId.ssId, + session->ssId.length); + limLog(mac_ctx, LOG1, FL("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; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg)) + { + limLog(mac_ctx, LOGE, FL("%s failed to post msg to self "), + __func__); + vos_mem_free((void *)sae_info); + status = VOS_STATUS_E_FAILURE; + } + + session->limMlmState = eLIM_MLM_WT_SAE_AUTH_STATE; + + MTRACE(macTrace(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(macTrace(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) { + limLog(mac_ctx, LOGE, + FL("could not start Auth SAE timer")); + } + return status; +} +#else +static VOS_STATUS lim_process_mlm_auth_req_sae(tpAniSirGlobal mac_ctx, + tpPESession session) +{ + return VOS_STATUS_E_NOSUPPORT; +} +#endif /** * limProcessMlmAuthReq() @@ -2411,7 +2544,20 @@ limProcessMlmAuthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) pMac->lim.gpLimMlmAuthReq->peerMacAddr); psessionEntry->limPrevMlmState = psessionEntry->limMlmState; - psessionEntry->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE; + if ((pMac->lim.gpLimMlmAuthReq->authType == eSIR_AUTH_TYPE_SAE) && + !psessionEntry->sae_pmk_cached) { + if (lim_process_mlm_auth_req_sae(pMac, psessionEntry) != + VOS_STATUS_SUCCESS) { + mlmAuthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } else { + limLog(pMac, LOG1, + FL("lim_process_mlm_auth_req_sae is successful")); + return; + } + } else { + psessionEntry->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE; + } MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); //assign appropriate sessionId to the timer object diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c index c182cc21dde6..3433c926af82 100644 --- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.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. * @@ -1906,6 +1906,32 @@ static void __limProcessClearDfsChannelList(tpAniSirGlobal pMac, 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; + + VOS_TRACE(VOS_MODULE_ID_PE, + VOS_TRACE_LEVEL_DEBUG, + FL("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 + /** * __limProcessSmeJoinReq() * @@ -2241,6 +2267,7 @@ __limProcessSmeJoinReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) #endif psessionEntry->txLdpcIniFeatureEnabled = pSmeJoinReq->txLdpcIniFeatureEnabled; lim_update_fils_config(psessionEntry, pSmeJoinReq); + lim_update_sae_config(psessionEntry, pSmeJoinReq); if (psessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) { psessionEntry->limSystemRole = eLIM_STA_ROLE; diff --git a/CORE/MAC/src/pe/lim/limSecurityUtils.c b/CORE/MAC/src/pe/lim/limSecurityUtils.c index 67fa19865fb2..64b0e8daa430 100644 --- a/CORE/MAC/src/pe/lim/limSecurityUtils.c +++ b/CORE/MAC/src/pe/lim/limSecurityUtils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2017, 2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -506,10 +506,15 @@ limRestoreFromAuthState(tpAniSirGlobal pMac, tSirResultCodes resultCode, tANI_U1 * retry is needed also cancel the auth rety timer */ pMac->auth_ack_status = LIM_AUTH_ACK_RCD_SUCCESS; + + /* Auth retry and AUth failure timers are not started for SAE */ + /* 'Change' timer for future activations */ + if (tx_timer_running(&pMac->lim.limTimers. + g_lim_periodic_auth_retry_timer)) + limDeactivateAndChangeTimer(pMac, eLIM_AUTH_RETRY_TIMER); /* 'Change' timer for future activations */ - limDeactivateAndChangeTimer(pMac, eLIM_AUTH_RETRY_TIMER); - // 'Change' timer for future activations - limDeactivateAndChangeTimer(pMac, eLIM_AUTH_FAIL_TIMER); + if (tx_timer_running(&pMac->lim.limTimers.gLimAuthFailureTimer)) + limDeactivateAndChangeTimer(pMac, eLIM_AUTH_FAIL_TIMER); sirCopyMacAddr(currentBssId,sessionEntry->bssId); diff --git a/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/CORE/MAC/src/pe/lim/limSendManagementFrames.c index 8be9c69cc77d..89add77896ee 100644 --- a/CORE/MAC/src/pe/lim/limSendManagementFrames.c +++ b/CORE/MAC/src/pe/lim/limSendManagementFrames.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. * @@ -5887,3 +5887,78 @@ returnAfterError: return nSirStatus; } // End limSendSaQueryResponseFrame #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; + eHalStatus hal_status; + uint8_t sme_session_id = 0; + tpPESession session; + + sme_session_id = mb_msg->session_id; + session = pe_find_session_by_sme_session_id(mac_ctx, sme_session_id); + if (session == NULL) { + limLog(mac_ctx, LOGP, + FL("session not found for given sme session")); + return; + } + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + session->peSessionId, fc->subType)); + mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD; + hal_status = halTxFrameWithTxComplete(mac_ctx, packet, + (uint16_t)msg_len, + HAL_TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, + 7, limTxComplete, frame, + lim_auth_tx_complete_cnf, + 0, sme_session_id, false); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + session->peSessionId, hal_status)); + if (!HAL_STATUS_SUCCESS(hal_status)) { + limLog(mac_ctx, LOGP, + FL("*** Could not send Auth frame, retCode=%X ***"), + hal_status); + mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE; + limDiagEventReport(mac_ctx, WLAN_PE_DIAG_AUTH_REQ_EVENT, + session, eSIR_FAILURE, eSIR_FAILURE); + /* Pkt will be freed up by the callback */ + } +} + +void lim_send_mgmt_frame_tx(tpAniSirGlobal mac_ctx, + tpSirMsgQ msg) +{ + struct sir_mgmt_msg *mb_msg = (struct sir_mgmt_msg *)msg->bodyptr; + uint32_t msg_len; + tpSirMacFrameCtl fc = (tpSirMacFrameCtl)mb_msg->data; + uint8_t sme_session_id; + eHalStatus halstatus; + uint8_t *frame; + void *packet; + + msg_len = mb_msg->msg_len - sizeof(*mb_msg); + limLog(mac_ctx, LOG1, FL("sending fc->type: %d fc->subType: %d"), + fc->type, fc->subType); + sme_session_id = mb_msg->session_id; + halstatus = palPktAlloc(mac_ctx->hHdd, HAL_TXRX_FRM_802_11_MGMT, + (uint16_t)msg_len, (void **)&frame, + (void **)&packet); + if (!HAL_STATUS_SUCCESS(halstatus)) { + limLog(mac_ctx, LOGP, + FL("call to bufAlloc failed for AUTH frame")); + return; + } + vos_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/limTimerUtils.c b/CORE/MAC/src/pe/lim/limTimerUtils.c index c4c4a0fda3bc..d6180093916c 100644 --- a/CORE/MAC/src/pe/lim/limTimerUtils.c +++ b/CORE/MAC/src/pe/lim/limTimerUtils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2016, 2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -56,6 +56,11 @@ #define LIM_JOIN_PROBE_REQ_TIMER_MS 200 #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 //default beacon interval value used in HB timer interval calculation #define LIM_HB_TIMER_BEACON_INTERVAL 100 @@ -428,6 +433,20 @@ limCreateTimers(tpAniSirGlobal pMac) goto err_timer; } + /* + * SAE auth timer of 5secs. This is required for duration of entire SAE + * authentication. + */ + if ((tx_timer_create(&pMac->lim.limTimers.sae_auth_timer, + "SAE AUTH Timer", + limTimerHandler, SIR_LIM_AUTH_SAE_TIMEOUT, + SYS_MS_TO_TICKS(LIM_AUTH_SAE_TIMER_MS), 0, + TX_NO_ACTIVATE)) != TX_SUCCESS) { + limLog(pMac, LOGP, + FL("could not create SAE AUTH Timer")); + goto err_timer; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, &cfgValue) != eSIR_SUCCESS) { @@ -752,6 +771,7 @@ limCreateTimers(tpAniSirGlobal pMac) tx_timer_delete(&pMac->lim.limTimers.gLimMinChannelTimer); 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) { @@ -1654,6 +1674,24 @@ limDeactivateAndChangeTimer(tpAniSirGlobal pMac, tANI_U32 timerId) } break; + case eLIM_AUTH_SAE_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.sae_auth_timer) + != TX_SUCCESS) { + limLog(pMac, LOGP, FL("Unable to deactivate SAE auth timer")); + return; + } + + /* 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) { + limLog(pMac, LOGP, FL("unable to change SAE auth timer")); + return; + } + + break; + default: // Invalid timerId. Log error break; diff --git a/CORE/MAC/src/pe/lim/limTimerUtils.h b/CORE/MAC/src/pe/lim/limTimerUtils.h index 3f4243a8ae56..50303a232055 100644 --- a/CORE/MAC/src/pe/lim/limTimerUtils.h +++ b/CORE/MAC/src/pe/lim/limTimerUtils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2016, 2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -78,7 +78,8 @@ enum 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/limTypes.h b/CORE/MAC/src/pe/lim/limTypes.h index f46dd6c09904..8762a85445fa 100644 --- a/CORE/MAC/src/pe/lim/limTypes.h +++ b/CORE/MAC/src/pe/lim/limTypes.h @@ -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. * @@ -1045,4 +1045,14 @@ void lim_process_rx_channel_status_event(tpAniSirGlobal mac_ctx, void *buf); int limProcessRemainOnChnlReq(tpAniSirGlobal pMac, tANI_U32 *pMsg); void limRemainOnChnRsp(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data); +/** + * 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, + tpSirMsgQ msg); + #endif /* __LIM_TYPES_H */ diff --git a/CORE/MAC/src/pe/lim/limUtils.c b/CORE/MAC/src/pe/lim/limUtils.c index 0877b3df505c..bceaee6af234 100644 --- a/CORE/MAC/src/pe/lim/limUtils.c +++ b/CORE/MAC/src/pe/lim/limUtils.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. * @@ -759,6 +759,9 @@ limCleanupMlm(tpAniSirGlobal pMac) tx_timer_deactivate(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer); tx_timer_delete(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer); + tx_timer_deactivate(&pMac->lim.limTimers.sae_auth_timer); + tx_timer_delete(&pMac->lim.limTimers.sae_auth_timer); + pMac->lim.gLimTimersCreated = 0; } diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h index f3df74382da7..c6a5480fd45c 100644 --- a/CORE/SME/inc/csrApi.h +++ b/CORE/SME/inc/csrApi.h @@ -569,6 +569,7 @@ typedef enum eCSR_ROAM_NDP_STATUS_UPDATE, eCSR_ROAM_UPDATE_SCAN_RESULT, + eCSR_ROAM_SAE_COMPUTE, }eRoamCmdStatus; @@ -1573,6 +1574,9 @@ typedef struct tagCsrRoamInfo uint16_t fils_seq_num; struct fils_join_rsp_params *fils_join_rsp; #endif +#ifdef WLAN_FEATURE_SAE + struct sir_sae_info *sae_info; +#endif }tCsrRoamInfo; @@ -1914,7 +1918,12 @@ typedef eHalStatus (*csrRoamSessionCloseCallback)(void *pContext); ///////////////////////////////////////////Common Roam ends - +#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 /* --------------------------------------------------------------------------- \fn csrSetChannels diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h index be1aca8d99da..d46689b566a3 100644 --- a/CORE/SME/inc/sme_Api.h +++ b/CORE/SME/inc/sme_Api.h @@ -4989,4 +4989,34 @@ typedef struct { eHalStatus sme_hpcs_pulse_params_conf_cmd(tHalHandle hHal, tSirHpcsPulseParmasConfig *pHpcsPulseParams); +/** + * 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: eHalStatus + */ +eHalStatus 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: HAL_STATUS + */ +eHalStatus sme_handle_sae_msg(tHalHandle hal, uint8_t session_id, + uint8_t sae_status); +#else +static inline eHalStatus sme_handle_sae_msg(tHalHandle hal, uint8_t session_id, + uint8_t sae_status) +{ + return eHAL_STATUS_SUCCESS; +} +#endif + #endif //#if !defined( __SME_API_H ) diff --git a/CORE/SME/inc/sme_Trace.h b/CORE/SME/inc/sme_Trace.h index cc78f069d641..d5fca558c63c 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, 2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -152,6 +152,7 @@ enum { 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/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c index cf5386c0a0b5..71819efc92e6 100644 --- a/CORE/SME/src/csr/csrApiRoam.c +++ b/CORE/SME/src/csr/csrApiRoam.c @@ -122,6 +122,52 @@ static tCsrRoamSession csrRoamRoamSession[CSR_ROAM_SESSION_MAX]; /*-------------------------------------------------------------------------- Type declarations ------------------------------------------------------------------------*/ +#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 VOS_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) { + smsLog(mac_ctx, LOGE, "SAE info is NULL"); + return VOS_STATUS_E_FAILURE; + } + + smsLog(mac_ctx, LOG1, FL("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 VOS_STATUS_E_FAILURE; + + roam_info.sae_info = sae_info; + csrRoamCallCallback(mac_ctx, session_id, &roam_info, + 0, eCSR_ROAM_SAE_COMPUTE, + eCSR_ROAM_RESULT_NONE); + + return VOS_STATUS_SUCCESS; +} +#else +static inline VOS_STATUS csr_sae_callback(tpAniSirGlobal mac_ctx, + tSirSmeRsp *msg_ptr) +{ + return VOS_STATUS_SUCCESS; +} +#endif + #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR int diagAuthTypeFromCSRType(eCsrAuthType authType) { @@ -9704,6 +9750,11 @@ void csrRoamingStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ) } break; + case eWNI_SME_TRIGGER_SAE: + smsLog(pMac, LOG1, FL("Invoke SAE callback")); + csr_sae_callback(pMac, pSmeRsp); + break; + default: smsLog(pMac, LOG1, FL("Unexpected message type = %d[0x%X] received in substate %s"), @@ -14374,6 +14425,37 @@ static void csr_update_fils_connection_info(tCsrRoamProfile *profile, { } #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; + + vos_mem_copy(pmkid_cache.BSSID, + csr_join_req->bssDescription.bssId, VOS_MAC_ADDR_SIZE); + + csr_join_req->sae_pmk_cached = + csr_lookup_pmkid_using_bssid(mac, session, &pmkid_cache, &index); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_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 + ////////////////////Mail box @@ -14451,7 +14533,6 @@ csrPrepareJoinReassocReqBuffer(tpAniSirGlobal pMac, *pBuf++ = pMac->sub20_channelwidth; csr_update_fils_connection_info(pProfile, &pBuf); - *pBuf++ = uapsdMask; // move the entire BssDescription into the join request. @@ -15191,6 +15272,7 @@ eHalStatus csrSendJoinReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDe csrPrepareJoinReassocReqBuffer(pMac, pBssDescription, pBuf, (tANI_U8)pProfile->uapsd_mask, messageType, pProfile); + csr_update_sae_config(pMsg, pMac, pSession); pBuf += used_length; /* @@ -18355,6 +18437,14 @@ eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 sessionId, smsLog( pMac, LOGE,"Roam Scan Offload is already started"); return eHAL_STATUS_FAILURE; } + + /* Roaming is not supported currently for SAE authentication */ + if (pSession->pCurRoamProfile && + CSR_IS_AUTH_TYPE_SAE( + pSession->pCurRoamProfile->AuthType.authType[0])) { + smsLog(pMac, LOGE, "Roaming not suppprted for SAE connection"); + return eHAL_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 the FW only * if the Infra Station is in a connected state.A connected station could also be diff --git a/CORE/SME/src/csr/csrInsideApi.h b/CORE/SME/src/csr/csrInsideApi.h index 06e9ab886345..0a98bf84766f 100644 --- a/CORE/SME/src/csr/csrInsideApi.h +++ b/CORE/SME/src/csr/csrInsideApi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, 2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1088,6 +1088,19 @@ tANI_BOOLEAN csrElectedCountryInfo(tpAniSirGlobal pMac); void csrAddVoteForCountryInfo(tpAniSirGlobal pMac, tANI_U8 *pCountryCode); void csrClearVotesForCountryInfo(tpAniSirGlobal pMac); +/** + * 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 eHalStatus csr_send_ext_change_channel(tpAniSirGlobal mac_ctx, uint32_t channel, uint8_t session_id); diff --git a/CORE/SME/src/csr/csrUtil.c b/CORE/SME/src/csr/csrUtil.c index 9061d7405b09..bc583072e175 100644 --- a/CORE/SME/src/csr/csrUtil.c +++ b/CORE/SME/src/csr/csrUtil.c @@ -521,6 +521,7 @@ get_eRoamCmdStatus_str(eRoamCmdStatus val) CASE_RETURN_STR(eCSR_ROAM_ESE_ADJ_AP_REPORT_IND); CASE_RETURN_STR(eCSR_ROAM_ESE_BCN_REPORT_IND); #endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + CASE_RETURN_STR(eCSR_ROAM_SAE_COMPUTE); default: return "unknown"; } @@ -3659,16 +3660,7 @@ static bool csr_lookup_pmkid_using_ssid(tpAniSirGlobal mac, 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) diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index 9ef47384d525..00ed46764a26 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -8452,6 +8452,68 @@ eHalStatus sme_ConfigureResumeReq( tHalHandle hHal, return(status); } +/** + * 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: eHalStatus + */ +static eHalStatus sme_prepare_mgmt_tx(tHalHandle hal, uint8_t session_id, + const uint8_t *buf, uint32_t len) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + vos_msg_t vos_message; + struct sir_mgmt_msg *msg; + uint16_t msg_len; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + ("prepares auth frame")); + + msg_len = sizeof(*msg) + len; + msg = vos_mem_malloc(msg_len); + if (msg == NULL) { + status = eHAL_STATUS_FAILED_ALLOC; + } 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); + vos_mem_copy(msg->data, buf, len); + vos_message.bodyptr = msg; + vos_message.type = eWNI_SME_SEND_MGMT_FRAME_TX; + vos_status = vos_mq_post_message(VOS_MQ_ID_PE, + &vos_message); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + vos_mem_free(msg); + status = eHAL_STATUS_FAILURE; + } + } + + return status; +} + +eHalStatus sme_send_mgmt_tx(tHalHandle hal, uint8_t session_id, + const uint8_t *buf, uint32_t len) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal mac = PMAC_STRUCT(hal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SEND_MGMT_TX, session_id, 0)); + + status = sme_AcquireGlobalLock(&mac->sme); + if (HAL_STATUS_SUCCESS(status)) { + status = sme_prepare_mgmt_tx(hal, session_id, buf, len); + sme_ReleaseGlobalLock(&mac->sme); + } + + return status; +} + #ifdef WLAN_FEATURE_EXTWOW_SUPPORT /* --------------------------------------------------------------------------- @@ -21066,3 +21128,46 @@ uint32_t sme_unpack_rsn_ie(tHalHandle hal, uint8_t *buf, return dot11fUnpackIeRSN(mac_ctx, buf, buf_len, rsn_ie); } + +#ifdef WLAN_FEATURE_SAE +eHalStatus sme_handle_sae_msg(tHalHandle hal, uint8_t session_id, +uint8_t sae_status) +{ + eHalStatus hal_status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal mac = PMAC_STRUCT(hal); + struct sir_sae_msg *sae_msg; + vos_msg_t vos_message; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + hal_status = sme_AcquireGlobalLock(&mac->sme); + if (HAL_STATUS_SUCCESS(hal_status)) { + sae_msg = vos_mem_malloc(sizeof(*sae_msg)); + if (!sae_msg) { + hal_status = eHAL_STATUS_FAILED_ALLOC; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "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; + vos_message.bodyptr = sae_msg; + vos_message.type = eWNI_SME_SEND_SAE_MSG; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "SAE: sae_status %d session_id %d", + sae_msg->sae_status, + sae_msg->session_id); + + vos_status = vos_mq_post_message(VOS_MQ_ID_PE, + &vos_message); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + vos_mem_free(sae_msg); + hal_status = eHAL_STATUS_FAILURE; + } + } + sme_ReleaseGlobalLock(&mac->sme); + } + + return hal_status; +} +#endif diff --git a/CORE/SYS/legacy/src/utils/src/macTrace.c b/CORE/SYS/legacy/src/utils/src/macTrace.c index e4cf1cd09f0f..0b0d500e9e77 100644 --- a/CORE/SYS/legacy/src/utils/src/macTrace.c +++ b/CORE/SYS/legacy/src/utils/src/macTrace.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. * @@ -589,6 +589,9 @@ tANI_U8* macTraceGetSmeMsgString(tANI_U16 smeMsg) CASE_RETURN_STRING(eWNI_SME_NAN_EVENT); #endif CASE_RETURN_STRING(eWNI_SME_REGISTER_P2P_ACK_CB); + 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((tANI_U8*)"UNKNOWN"); @@ -1054,6 +1057,7 @@ tANI_U8* macTraceGetLimMsgString(tANI_U16 limMsg) 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); |
