qcacld-3.0: Add support for cross-SAE AKM roam

Pass the akm explicitly in the external auth
request to the userspace since there are many
SAE AKM suites.

Change-Id: Ifef8657f7ef75b402aa670813eba6adc5ab9853a
CRs-Fixed: 3355395
This commit is contained in:
Surya Prakash Sivaraj
2022-12-05 18:23:35 +05:30
committed by Madan Koyyalamudi
parent 13adfb9dfa
commit ae712fa3de
13 changed files with 91 additions and 21 deletions

View File

@@ -2325,11 +2325,13 @@ struct roam_stats_event {
* @vdev_id: vdev id
* @ap_bssid: SAE authentication offload AP MAC Address
* @ta: SAE authentication offload Tx MAC Address
* @akm: SAE AKM type
*/
struct auth_offload_event {
uint8_t vdev_id;
struct qdf_mac_addr ap_bssid;
struct qdf_mac_addr ta;
uint32_t akm;
};
/*

View File

@@ -3314,6 +3314,7 @@ extract_auth_offload_event_tlv(wmi_unified_t wmi_handle,
}
auth_event->vdev_id = rso_auth_start_ev->vdev_id;
auth_event->akm = rso_auth_start_ev->akm_suite_type;
WMI_MAC_ADDR_TO_CHAR_ARRAY(&rso_auth_start_ev->candidate_ap_bssid,
auth_event->ap_bssid.bytes);
@@ -3327,10 +3328,10 @@ extract_auth_offload_event_tlv(wmi_unified_t wmi_handle,
}
wmi_debug("Received Roam auth offload event for bss:"
QDF_MAC_ADDR_FMT " ta:" QDF_MAC_ADDR_FMT " vdev_id: %d",
QDF_MAC_ADDR_FMT " ta:" QDF_MAC_ADDR_FMT " vdev_id: %d akm: %d",
QDF_MAC_ADDR_REF(auth_event->ap_bssid.bytes),
QDF_MAC_ADDR_REF(auth_event->ta.bytes),
auth_event->vdev_id);
auth_event->vdev_id, auth_event->akm);
return QDF_STATUS_SUCCESS;
}

View File

@@ -261,6 +261,34 @@ void wlan_hdd_sae_copy_ta_addr(struct cfg80211_external_auth_params *params,
{
}
#endif
/**
* wlan_hdd_get_keymgmt_for_sae_akm() - Get the keymgmt OUI
* corresponding to the SAE AKM type
* @akm: AKM type
*
* This API is used to get the keymgmt OUI for the SAE AKM type.
* Return: keymgmt OUI
*/
static uint32_t
wlan_hdd_get_keymgmt_for_sae_akm(uint32_t akm)
{
if (akm == WLAN_AKM_SAE)
return WLAN_AKM_SUITE_SAE;
else if (akm == WLAN_AKM_FT_SAE)
return WLAN_AKM_SUITE_FT_OVER_SAE;
else if (akm == WLAN_AKM_SAE_EXT_KEY)
return WLAN_AKM_SUITE_SAE_EXT_KEY;
/**
* Legacy FW doesn't support SAE-EXK-KEY or
* Cross-SAE_AKM roaming. In such cases, send
* SAE for both SAE and FT-SAE AKMs. The supplicant
* has backward compatibility to handle this case.
*/
else
return WLAN_AKM_SUITE_SAE;
}
/**
* wlan_hdd_sae_callback() - Sends SAE info to supplicant
* @adapter: pointer adapter context
@@ -288,10 +316,8 @@ static void wlan_hdd_sae_callback(struct hdd_adapter *adapter,
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.key_mgmt_suite =
wlan_hdd_get_keymgmt_for_sae_akm(sae_info->akm);
params.action = NL80211_EXTERNAL_AUTH_START;
qdf_mem_copy(params.bssid, sae_info->peer_mac_addr.bytes,

View File

@@ -527,6 +527,7 @@ static const u32 hdd_sta_akm_suites[] = {
RSN_AUTH_KEY_MGMT_OSEN,
WAPI_PSK_AKM_SUITE,
WAPI_CERT_AKM_SUITE,
WLAN_AKM_SUITE_SAE_EXT_KEY,
};
/*akm suits supported by AP*/

View File

@@ -188,6 +188,10 @@ extern const struct nla_policy wlan_hdd_wisa_cmd_policy[
#define WLAN_AKM_SUITE_FT_EAP_SHA_384 0x000FAC0D
#endif
#ifndef WLAN_AKM_SUITE_SAE_EXT_KEY
#define WLAN_AKM_SUITE_SAE_EXT_KEY 0x000FAC18
#endif
#ifdef FEATURE_WLAN_TDLS
#define WLAN_IS_TDLS_SETUP_ACTION(action) \
((TDLS_SETUP_REQUEST <= action) && \

View File

@@ -651,7 +651,8 @@ struct sme_ready_req {
uint16_t length;
QDF_STATUS (*csr_roam_auth_event_handle_cb)(struct mac_context *mac,
uint8_t vdev_id,
struct qdf_mac_addr bssid);
struct qdf_mac_addr bssid,
uint32_t akm);
pe_roam_synch_fn_t pe_roam_synch_cb;
stop_roaming_fn_t stop_roaming_cb;
QDF_STATUS (*sme_msg_cb)(struct mac_context *mac,
@@ -5157,6 +5158,7 @@ struct sir_roam_scan_stats {
* @vdev_id: vdev id
* @peer_mac_addr: peer MAC address
* @ssid: SSID
* @akm: key mgmt suite used
*/
struct sir_sae_info {
uint16_t msg_type;
@@ -5164,6 +5166,7 @@ struct sir_sae_info {
uint32_t vdev_id;
struct qdf_mac_addr peer_mac_addr;
tSirMacSSid ssid;
uint32_t akm;
};
/**

View File

@@ -590,6 +590,21 @@ static bool lim_is_preauth_ctx_exists(struct mac_context *mac_ctx,
}
#ifdef WLAN_FEATURE_SAE
static inline
uint32_t lim_get_sae_keymgmt_suite(uint32_t keymgmt)
{
/* Select the best SAE AKM suite supported */
if (QDF_HAS_PARAM(keymgmt, WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY))
return WLAN_AKM_SAE_EXT_KEY;
else if (QDF_HAS_PARAM(keymgmt, WLAN_CRYPTO_KEY_MGMT_FT_SAE))
return WLAN_AKM_FT_SAE;
else if (QDF_HAS_PARAM(keymgmt, WLAN_CRYPTO_KEY_MGMT_SAE))
return WLAN_AKM_SAE;
pe_err("Invalid SAE Keymgmt suite %d", keymgmt);
return WLAN_AKM_SAE;
}
QDF_STATUS lim_trigger_auth_req_sae(struct mac_context *mac_ctx,
struct pe_session *session,
struct qdf_mac_addr *peer_bssid)
@@ -597,6 +612,7 @@ QDF_STATUS lim_trigger_auth_req_sae(struct mac_context *mac_ctx,
QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
struct sir_sae_info *sae_info;
struct scheduler_msg msg = {0};
uint32_t keymgmt;
sae_info = qdf_mem_malloc(sizeof(*sae_info));
if (!sae_info)
@@ -607,16 +623,20 @@ QDF_STATUS lim_trigger_auth_req_sae(struct mac_context *mac_ctx,
sae_info->vdev_id = session->smeSessionId;
qdf_copy_macaddr(&sae_info->peer_mac_addr, peer_bssid);
keymgmt = wlan_crypto_get_param(session->vdev,
WLAN_CRYPTO_PARAM_KEY_MGMT);
sae_info->akm = lim_get_sae_keymgmt_suite(keymgmt);
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 " QDF_SSID_FMT " " QDF_MAC_ADDR_FMT,
pe_debug("vdev_id %d ssid " QDF_SSID_FMT " " QDF_MAC_ADDR_FMT "akm %d",
sae_info->vdev_id,
QDF_SSID_REF(sae_info->ssid.length, sae_info->ssid.ssId),
QDF_MAC_ADDR_REF(sae_info->peer_mac_addr.bytes));
QDF_MAC_ADDR_REF(sae_info->peer_mac_addr.bytes),
sae_info->akm);
msg.type = eWNI_SME_TRIGGER_SAE;
msg.bodyptr = sae_info;

View File

@@ -597,16 +597,19 @@ bool csr_is_mcc_channel(struct mac_context *mac_ctx, uint32_t chan_freq);
* @mac_ctx: Global mac context pointer
* @vdev_id: Vdev id
* @bssid: candidate AP bssid
* @akm: candidate AKM
*/
QDF_STATUS
csr_roam_auth_offload_callback(struct mac_context *mac_ctx,
uint8_t vdev_id,
struct qdf_mac_addr bssid);
struct qdf_mac_addr bssid,
uint32_t akm);
#else
static inline QDF_STATUS
csr_roam_auth_offload_callback(struct mac_context *mac_ctx,
uint8_t vdev_id,
struct qdf_mac_addr bssid)
struct qdf_mac_addr bssid,
uint32_t akm)
{
return QDF_STATUS_E_NOSUPPORT;
}

View File

@@ -7626,6 +7626,7 @@ fail:
* @mac_ctx: Global mac context pointer
* @vdev_id: vdev id
* @roam_bssid: Candidate BSSID to roam
* @akm: Candidate AKM
*
* This function calls the hdd_sme_roam_callback with reason
* eCSR_ROAM_SAE_COMPUTE to trigger SAE auth to supplicant.
@@ -7633,7 +7634,8 @@ fail:
static QDF_STATUS
csr_process_roam_auth_sae_callback(struct mac_context *mac_ctx,
uint8_t vdev_id,
struct qdf_mac_addr roam_bssid)
struct qdf_mac_addr roam_bssid,
uint32_t akm)
{
struct csr_roam_info *roam_info;
struct sir_sae_info sae_info;
@@ -7651,6 +7653,7 @@ csr_process_roam_auth_sae_callback(struct mac_context *mac_ctx,
sae_info.msg_len = sizeof(sae_info);
sae_info.vdev_id = vdev_id;
sae_info.akm = akm;
wlan_cm_get_roam_offload_ssid(mac_ctx->psoc, vdev_id,
sae_info.ssid.ssId,
&sae_info.ssid.length);
@@ -7670,15 +7673,16 @@ csr_process_roam_auth_sae_callback(struct mac_context *mac_ctx,
static inline QDF_STATUS
csr_process_roam_auth_sae_callback(struct mac_context *mac_ctx,
uint8_t vdev_id,
struct qdf_mac_addr roam_bssid)
struct qdf_mac_addr roam_bssid,
uint32_t akm)
{
return QDF_STATUS_E_NOSUPPORT;
}
#endif
QDF_STATUS
csr_roam_auth_offload_callback(struct mac_context *mac_ctx,
uint8_t vdev_id, struct qdf_mac_addr bssid)
csr_roam_auth_offload_callback(struct mac_context *mac_ctx, uint8_t vdev_id,
struct qdf_mac_addr bssid, uint32_t akm)
{
QDF_STATUS status;
@@ -7686,7 +7690,8 @@ csr_roam_auth_offload_callback(struct mac_context *mac_ctx,
if (!QDF_IS_STATUS_SUCCESS(status))
return status;
status = csr_process_roam_auth_sae_callback(mac_ctx, vdev_id, bssid);
status = csr_process_roam_auth_sae_callback(mac_ctx, vdev_id,
bssid, akm);
sme_release_global_lock(&mac_ctx->sme);

View File

@@ -999,7 +999,8 @@ typedef struct {
QDF_STATUS (*csr_roam_auth_event_handle_cb)(struct mac_context *mac,
uint8_t vdev_id,
struct qdf_mac_addr bssid);
struct qdf_mac_addr bssid,
uint32_t akm);
QDF_STATUS (*pe_roam_synch_cb)(struct mac_context *mac,
uint8_t vdev_id,
struct roam_offload_synch_ind *roam_synch_data,

View File

@@ -731,7 +731,8 @@ QDF_STATUS wma_register_roaming_callbacks(
QDF_STATUS (*csr_roam_auth_event_handle_cb)(
struct mac_context *mac,
uint8_t vdev_id,
struct qdf_mac_addr bssid),
struct qdf_mac_addr bssid,
uint32_t akm),
pe_roam_synch_fn_t pe_roam_synch_cb,
QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac,
uint8_t vdev_id,
@@ -743,7 +744,8 @@ static inline QDF_STATUS wma_register_roaming_callbacks(
QDF_STATUS (*csr_roam_auth_event_handle_cb)(
struct mac_context *mac,
uint8_t vdev_id,
struct qdf_mac_addr bssid),
struct qdf_mac_addr bssid,
uint32_t akm),
pe_roam_synch_fn_t pe_roam_synch_cb,
QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac,
uint8_t vdev_id,

View File

@@ -3984,7 +3984,8 @@ QDF_STATUS wma_de_register_mgmt_frm_client(void)
QDF_STATUS wma_register_roaming_callbacks(
QDF_STATUS (*csr_roam_auth_event_handle_cb)(struct mac_context *mac,
uint8_t vdev_id,
struct qdf_mac_addr bssid),
struct qdf_mac_addr bssid,
uint32_t akm),
pe_roam_synch_fn_t pe_roam_synch_cb,
QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac,
uint8_t vdev_id,

View File

@@ -296,7 +296,8 @@ cm_handle_auth_offload(struct auth_offload_event *auth_event)
auth_event->vdev_id,
auth_event->ta);
status = wma->csr_roam_auth_event_handle_cb(mac_ctx, auth_event->vdev_id,
auth_event->ap_bssid);
auth_event->ap_bssid,
auth_event->akm);
if (QDF_IS_STATUS_ERROR(status)) {
wma_err_rl("Trigger pre-auth failed");
return QDF_STATUS_E_FAILURE;