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:

committed by
Madan Koyyalamudi

parent
13adfb9dfa
commit
ae712fa3de
@@ -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;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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*/
|
||||
|
@@ -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) && \
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user