|
@@ -62,6 +62,7 @@
|
|
|
#include "wlan_mlme_public_struct.h"
|
|
|
#include <wlan_crypto_global_api.h>
|
|
|
|
|
|
+#define RSN_AUTH_KEY_MGMT_SAE WLAN_RSN_SEL(WLAN_AKM_SAE)
|
|
|
#define MAX_PWR_FCC_CHAN_12 8
|
|
|
#define MAX_PWR_FCC_CHAN_13 2
|
|
|
|
|
@@ -10539,6 +10540,54 @@ static QDF_STATUS csr_send_reset_ap_caps_changed(struct mac_context *mac,
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
+static bool csr_is_sae_akm_present(tDot11fIERSN * const rsn_ie)
|
|
|
+{
|
|
|
+ uint16_t i;
|
|
|
+
|
|
|
+ if (rsn_ie->akm_suite_cnt > 6) {
|
|
|
+ sme_debug("Invalid akm_suite_cnt in Rx RSN IE");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < rsn_ie->akm_suite_cnt; i++) {
|
|
|
+ if (LE_READ_4(rsn_ie->akm_suite[i]) == RSN_AUTH_KEY_MGMT_SAE) {
|
|
|
+ sme_debug("SAE AKM present");
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+static bool csr_is_sae_peer_allowed(struct mac_context *mac_ctx,
|
|
|
+ struct assoc_ind *assoc_ind,
|
|
|
+ struct csr_roam_session *session,
|
|
|
+ tSirMacAddr peer_mac_addr,
|
|
|
+ tDot11fIERSN *rsn_ie,
|
|
|
+ tSirMacStatusCodes *mac_status_code)
|
|
|
+{
|
|
|
+ bool is_allowed = false;
|
|
|
+
|
|
|
+ /* Allow the peer if it's SAE authenticated */
|
|
|
+ if (assoc_ind->is_sae_authenticated)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ /* Allow the peer with valid PMKID */
|
|
|
+ if (!rsn_ie->pmkid_count) {
|
|
|
+ *mac_status_code = eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;
|
|
|
+ sme_debug("No PMKID present in RSNIE; Tried to use SAE AKM after non-SAE authentication");
|
|
|
+ } else if (csr_is_pmkid_found_for_peer(mac_ctx, session, peer_mac_addr,
|
|
|
+ &rsn_ie->pmkid[0][0],
|
|
|
+ rsn_ie->pmkid_count)) {
|
|
|
+ sme_debug("Valid PMKID found for SAE peer");
|
|
|
+ is_allowed = true;
|
|
|
+ } else {
|
|
|
+ *mac_status_code = eSIR_MAC_INVALID_PMKID;
|
|
|
+ sme_debug("No valid PMKID found for SAE peer");
|
|
|
+ }
|
|
|
+
|
|
|
+ return is_allowed;
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
|
|
|
{
|
|
@@ -10548,6 +10597,7 @@ csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
|
|
|
struct csr_roam_info *roam_info_ptr = NULL;
|
|
|
struct assoc_ind *pAssocInd;
|
|
|
struct csr_roam_info roam_info;
|
|
|
+ tSirMacStatusCodes mac_status_code = eSIR_MAC_SUCCESS_STATUS;
|
|
|
|
|
|
qdf_mem_zero(&roam_info, sizeof(roam_info));
|
|
|
sme_debug("Receive WNI_SME_ASSOC_IND from SME");
|
|
@@ -10623,13 +10673,35 @@ csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
|
|
|
status = csr_roam_call_callback(mac_ctx, sessionId,
|
|
|
roam_info_ptr, 0, eCSR_ROAM_INFRA_IND,
|
|
|
eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND);
|
|
|
- if (!QDF_IS_STATUS_SUCCESS(status))
|
|
|
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
|
|
|
/* Refused due to Mac filtering */
|
|
|
roam_info_ptr->statusCode = eSIR_SME_ASSOC_REFUSED;
|
|
|
+ } else if (pAssocInd->rsnIE.length) {
|
|
|
+ tDot11fIERSN rsn_ie = {0};
|
|
|
+
|
|
|
+ if (dot11f_unpack_ie_rsn(mac_ctx,
|
|
|
+ pAssocInd->rsnIE.rsnIEdata + 2,
|
|
|
+ pAssocInd->rsnIE.length - 2,
|
|
|
+ &rsn_ie, false)
|
|
|
+ != DOT11F_PARSE_SUCCESS ||
|
|
|
+ (csr_is_sae_akm_present(&rsn_ie) &&
|
|
|
+ !csr_is_sae_peer_allowed(mac_ctx, pAssocInd,
|
|
|
+ session,
|
|
|
+ pAssocInd->peerMacAddr,
|
|
|
+ &rsn_ie,
|
|
|
+ &mac_status_code))) {
|
|
|
+ status = QDF_STATUS_E_INVAL;
|
|
|
+ roam_info_ptr->statusCode =
|
|
|
+ eSIR_SME_ASSOC_REFUSED;
|
|
|
+ sme_debug("SAE peer not allowed: Status: %d",
|
|
|
+ mac_status_code);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* Send Association completion message to PE */
|
|
|
- status = csr_send_assoc_cnf_msg(mac_ctx, pAssocInd, status);
|
|
|
+ status = csr_send_assoc_cnf_msg(mac_ctx, pAssocInd, status,
|
|
|
+ mac_status_code);
|
|
|
/*
|
|
|
* send a message to CSR itself just to avoid the EAPOL frames going
|
|
|
* OTA before association response
|
|
@@ -15499,7 +15571,8 @@ QDF_STATUS csr_send_mb_deauth_cnf_msg(struct mac_context *mac,
|
|
|
|
|
|
QDF_STATUS csr_send_assoc_cnf_msg(struct mac_context *mac,
|
|
|
struct assoc_ind *pAssocInd,
|
|
|
- QDF_STATUS Halstatus)
|
|
|
+ QDF_STATUS Halstatus,
|
|
|
+ tSirMacStatusCodes mac_status_code)
|
|
|
{
|
|
|
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
|
|
struct assoc_cnf *pMsg;
|
|
@@ -15512,10 +15585,12 @@ QDF_STATUS csr_send_assoc_cnf_msg(struct mac_context *mac,
|
|
|
return QDF_STATUS_E_NOMEM;
|
|
|
pMsg->messageType = eWNI_SME_ASSOC_CNF;
|
|
|
pMsg->length = sizeof(*pMsg);
|
|
|
- if (QDF_IS_STATUS_SUCCESS(Halstatus))
|
|
|
+ if (QDF_IS_STATUS_SUCCESS(Halstatus)) {
|
|
|
pMsg->statusCode = eSIR_SME_SUCCESS;
|
|
|
- else
|
|
|
+ } else {
|
|
|
pMsg->statusCode = eSIR_SME_ASSOC_REFUSED;
|
|
|
+ pMsg->mac_status_code = mac_status_code;
|
|
|
+ }
|
|
|
/* bssId */
|
|
|
qdf_mem_copy(pMsg->bssid.bytes, pAssocInd->bssId,
|
|
|
QDF_MAC_ADDR_SIZE);
|