diff --git a/components/mlme/core/inc/wlan_mlme_main.h b/components/mlme/core/inc/wlan_mlme_main.h index 087c1c2ef5d2..d485dca15a85 100644 --- a/components/mlme/core/inc/wlan_mlme_main.h +++ b/components/mlme/core/inc/wlan_mlme_main.h @@ -127,6 +127,7 @@ mlme_vdev_object_destroyed_notification(struct wlan_objmgr_vdev *vdev, #endif +#ifndef CRYPTO_SET_KEY_CONVERGED /** * wlan_peer_set_unicast_cipher() - set unicast cipher * @peer: PEER object @@ -168,7 +169,7 @@ uint32_t wlan_peer_get_unicast_cipher(struct wlan_objmgr_peer *peer) return peer_priv->ucast_key_cipher; } - +#endif /** * wma_get_peer_mic_len() - get mic hdr len and mic length for peer * @psoc: psoc diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index deb0babfce0e..baed8b88571f 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -26,6 +26,7 @@ #include "wlan_scan_public_structs.h" #include "wlan_vdev_mlme_api.h" #include "wlan_mlme_api.h" +#include #define NUM_OF_SOUNDING_DIMENSIONS 1 /*Nss - 1, (Nss = 2 for 2x2)*/ @@ -239,6 +240,61 @@ out: return status; } +#ifdef CRYPTO_SET_KEY_CONVERGED +QDF_STATUS mlme_get_peer_mic_len(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *peer_mac, uint8_t *mic_len, + uint8_t *mic_hdr_len) +{ + struct wlan_objmgr_peer *peer; + uint32_t key_cipher; + + if (!psoc || !mic_len || !mic_hdr_len || !peer_mac) { + mlme_debug("psoc/mic_len/mic_hdr_len/peer_mac null"); + return QDF_STATUS_E_NULL_VALUE; + } + + peer = wlan_objmgr_get_peer(psoc, pdev_id, + peer_mac, WLAN_LEGACY_MAC_ID); + if (!peer) { + mlme_debug("Peer of peer_mac %pM not found", peer_mac); + return QDF_STATUS_E_INVAL; + } + + key_cipher = + wlan_crypto_get_peer_param(peer, + WLAN_CRYPTO_PARAM_UCAST_CIPHER); + wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID); + + if (key_cipher & (1 << WLAN_CRYPTO_CIPHER_AES_GCM) || + key_cipher & (1 << WLAN_CRYPTO_CIPHER_AES_GCM_256)) { + *mic_hdr_len = WLAN_IEEE80211_GCMP_HEADERLEN; + *mic_len = WLAN_IEEE80211_GCMP_MICLEN; + } else { + *mic_hdr_len = IEEE80211_CCMP_HEADERLEN; + *mic_len = IEEE80211_CCMP_MICLEN; + } + mlme_debug("peer %pM hdr_len %d mic_len %d key_cipher 0x%x", peer_mac, + *mic_hdr_len, *mic_len, key_cipher); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +mlme_peer_object_created_notification(struct wlan_objmgr_peer *peer, + void *arg) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +mlme_peer_object_destroyed_notification(struct wlan_objmgr_peer *peer, + void *arg) +{ + return QDF_STATUS_SUCCESS; +} + +#else + QDF_STATUS mlme_get_peer_mic_len(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *peer_mac, uint8_t *mic_len, uint8_t *mic_hdr_len) @@ -334,6 +390,7 @@ mlme_peer_object_destroyed_notification(struct wlan_objmgr_peer *peer, return status; } +#endif static void mlme_init_chainmask_cfg(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_chainmask *chainmask_info) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index dcf38f5771f5..050f482c62b9 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -14834,6 +14834,9 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, if (errno) return errno; cipher = osif_nl_to_crypto_cipher_type(params->cipher); + if (pairwise) + wma_set_peer_ucast_cipher(mac_address.bytes, cipher); + switch (adapter->device_mode) { case QDF_IBSS_MODE: errno = wlan_hdd_add_key_ibss(adapter, pairwise, key_index, diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 8184ab3bbcb2..cabfbc596136 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -2558,6 +2558,17 @@ uint8_t wma_rx_invalid_peer_ind(uint8_t vdev_id, void *wh); struct wlan_objmgr_psoc *wma_get_psoc_from_scn_handle(void *scn_handle); #ifdef CRYPTO_SET_KEY_CONVERGED + +/** + * wma_set_peer_ucast_cipher() - Update unicast cipher fof the peer + * @mac_addr: peer mac address + * @cipher: peer cipher type + * + * Return: None + */ +void wma_set_peer_ucast_cipher(uint8_t *mac_addr, + enum wlan_crypto_cipher_type cipher); + /** * wma_update_set_key() - Update WMA layer for set key * @session_id: vdev session identifier diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index 85f8f729856d..90fd3005e527 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -5634,6 +5634,59 @@ static void wma_send_set_key_rsp(uint8_t session_id, bool pairwise, } } +static uint32_t wma_cipher_to_cap(enum wlan_crypto_cipher_type cipher) +{ + switch (cipher) { + case WLAN_CRYPTO_CIPHER_WEP: return WLAN_CRYPTO_CAP_WEP; + case WLAN_CRYPTO_CIPHER_WEP_40: return WLAN_CRYPTO_CAP_WEP; + case WLAN_CRYPTO_CIPHER_WEP_104: return WLAN_CRYPTO_CAP_WEP; + case WLAN_CRYPTO_CIPHER_AES_OCB: return WLAN_CRYPTO_CAP_AES; + case WLAN_CRYPTO_CIPHER_AES_CCM: return WLAN_CRYPTO_CAP_AES; + case WLAN_CRYPTO_CIPHER_AES_CCM_256: return WLAN_CRYPTO_CAP_AES; + case WLAN_CRYPTO_CIPHER_AES_GCM: return WLAN_CRYPTO_CAP_AES; + case WLAN_CRYPTO_CIPHER_AES_GCM_256: return WLAN_CRYPTO_CAP_AES; + case WLAN_CRYPTO_CIPHER_CKIP: return WLAN_CRYPTO_CAP_CKIP; + case WLAN_CRYPTO_CIPHER_TKIP: return WLAN_CRYPTO_CAP_TKIP_MIC; + case WLAN_CRYPTO_CIPHER_WAPI_SMS4: return WLAN_CRYPTO_CAP_WAPI_SMS4; + case WLAN_CRYPTO_CIPHER_WAPI_GCM4: return WLAN_CRYPTO_CAP_WAPI_GCM4; + case WLAN_CRYPTO_CIPHER_FILS_AEAD: return WLAN_CRYPTO_CAP_FILS_AEAD; + default: return 0; + } +} + +void wma_set_peer_ucast_cipher(uint8_t *mac_addr, + enum wlan_crypto_cipher_type cipher) +{ + int32_t set_val = 0, cipher_cap; + struct wlan_objmgr_peer *peer; + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + + if (!wma) { + wma_err("wma context is NULL"); + return; + } + + peer = wlan_objmgr_get_peer(wma->psoc, + wlan_objmgr_pdev_get_pdev_id(wma->pdev), + mac_addr, WLAN_LEGACY_WMA_ID); + if (!peer) { + wma_err("Peer of peer_mac %pM not found", mac_addr); + return; + } + cipher_cap = wma_cipher_to_cap(cipher); + MLME_SET_BIT(set_val, cipher_cap); + wlan_crypto_set_peer_param(peer, WLAN_CRYPTO_PARAM_CIPHER_CAP, + set_val); + set_val = 0; + MLME_SET_BIT(set_val, cipher); + wlan_crypto_set_peer_param(peer, WLAN_CRYPTO_PARAM_UCAST_CIPHER, + set_val); + wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); + + wma_debug("Set unicast cipher %x and cap %x for %pM", 1 << cipher, + 1 << cipher_cap, mac_addr); +} + static void wma_reset_ipn(struct wma_txrx_node *iface, uint8_t key_index) { if (key_index == WMA_IGTK_KEY_INDEX_4 || @@ -5659,9 +5712,6 @@ void wma_update_set_key(uint8_t session_id, bool pairwise, wma_info("iface not found for session id %d", session_id); wma_reset_ipn(iface, key_index); - if (iface && pairwise) - iface->ucast_key_cipher = - wlan_crypto_cipher_to_wmi_cipher(cipher_type); if (!pairwise && iface) { /* Its GTK release the wake lock */ wma_debug("Release set key wake lock"); diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index c0d4d1ebcfee..85da84bffd47 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -75,6 +75,7 @@ #include "wma_nan_datapath.h" #include "wlan_mlme_api.h" #include +#include #ifdef FEATURE_WLAN_EXTSCAN #define WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION WAKELOCK_DURATION_RECOMMENDED @@ -2467,8 +2468,71 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma, return 0; } +#ifdef CRYPTO_SET_KEY_CONVERGED static void wma_update_roamed_peer_unicast_cipher(tp_wma_handle wma, uint32_t uc_cipher, + uint32_t cipher_cap, + uint8_t *peer_mac) +{ + struct wlan_objmgr_peer *peer; + + if (!peer_mac) { + wma_err("wma ctx or peer mac is NULL"); + return; + } + + peer = wlan_objmgr_get_peer(wma->psoc, + wlan_objmgr_pdev_get_pdev_id(wma->pdev), + peer_mac, WLAN_LEGACY_WMA_ID); + if (!peer) { + wma_err("Peer of peer_mac %pM not found", peer_mac); + return; + } + wlan_crypto_set_peer_param(peer, WLAN_CRYPTO_PARAM_CIPHER_CAP, + cipher_cap); + wlan_crypto_set_peer_param(peer, WLAN_CRYPTO_PARAM_UCAST_CIPHER, + uc_cipher); + + wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); + + wma_debug("Set unicast cipher %x and cap %x for %pM", uc_cipher, + cipher_cap, peer_mac); +} + +static void wma_get_peer_uc_cipher(tp_wma_handle wma, uint8_t *peer_mac, + uint32_t *uc_cipher, uint32_t *cipher_cap) +{ + uint32_t cipher, cap; + struct wlan_objmgr_peer *peer; + + if (!peer_mac) { + WMA_LOGE("wma ctx or peer_mac is NULL"); + return; + } + peer = wlan_objmgr_get_peer(wma->psoc, + wlan_objmgr_pdev_get_pdev_id(wma->pdev), + peer_mac, WLAN_LEGACY_WMA_ID); + if (!peer) { + WMA_LOGE("Peer of peer_mac %pM not found", peer_mac); + return; + } + + cipher = wlan_crypto_get_peer_param(peer, + WLAN_CRYPTO_PARAM_UCAST_CIPHER); + cap = wlan_crypto_get_peer_param(peer, WLAN_CRYPTO_PARAM_CIPHER_CAP); + wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); + + if (uc_cipher) + *uc_cipher = cipher; + if (cipher_cap) + *cipher_cap = cap; +} + +#else + +static void wma_update_roamed_peer_unicast_cipher(tp_wma_handle wma, + uint32_t uc_cipher, + uint32_t cipher_cap, uint8_t *peer_mac) { struct wlan_objmgr_peer *peer; @@ -2488,31 +2552,35 @@ static void wma_update_roamed_peer_unicast_cipher(tp_wma_handle wma, wlan_peer_set_unicast_cipher(peer, uc_cipher); wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); + + wma_debug("Set unicast cipher %d for %pM", uc_cipher, peer_mac); } -static uint32_t wma_get_peer_uc_cipher(tp_wma_handle wma, uint8_t *peer_mac) +static void wma_get_peer_uc_cipher(tp_wma_handle wma, uint8_t *peer_mac, + uint32_t *uc_cipher, uint32_t *cipher_cap) { - uint32_t uc_cipher; + uint32_t cipher; struct wlan_objmgr_peer *peer; if (!peer_mac) { WMA_LOGE("peer_mac is NULL"); - return 0; + return; } peer = wlan_objmgr_get_peer(wma->psoc, wlan_objmgr_pdev_get_pdev_id(wma->pdev), peer_mac, WLAN_LEGACY_WMA_ID); if (!peer) { WMA_LOGE("Peer of peer_mac %pM not found", peer_mac); - return 0; + return; } - uc_cipher = wlan_peer_get_unicast_cipher(peer); + cipher = wlan_peer_get_unicast_cipher(peer); wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); - return uc_cipher; + if (uc_cipher) + *uc_cipher = cipher; } - +#endif /** * wma_roam_update_vdev() - Update the STA and BSS * @wma: Global WMA Handle @@ -2531,7 +2599,7 @@ static void wma_roam_update_vdev(tp_wma_handle wma, tDeleteStaParams *del_sta_params; tLinkStateParams *set_link_params; tAddStaParams *add_sta_params; - uint32_t uc_cipher; + uint32_t uc_cipher = 0, cipher_cap = 0; uint8_t vdev_id; vdev_id = roam_synch_ind_ptr->roamed_vdev_id; @@ -2569,13 +2637,14 @@ static void wma_roam_update_vdev(tp_wma_handle wma, * Get uc cipher of old peer to update new peer as it doesnt * change in roaming */ - uc_cipher = wma_get_peer_uc_cipher(wma, del_bss_params->bssid); + wma_get_peer_uc_cipher(wma, del_bss_params->bssid, &uc_cipher, + &cipher_cap); wma_delete_sta(wma, del_sta_params); wma_delete_bss(wma, del_bss_params); wma_set_linkstate(wma, set_link_params); /* Update new peer's uc cipher */ - wma_update_roamed_peer_unicast_cipher(wma, uc_cipher, + wma_update_roamed_peer_unicast_cipher(wma, uc_cipher, cipher_cap, roam_synch_ind_ptr->bssid.bytes); wma_add_bss(wma, (tpAddBssParams)roam_synch_ind_ptr->add_bss_params); wma_add_sta(wma, add_sta_params);