From 0c6d94dd3eaaae23954c28b04ea4792548b19d4c Mon Sep 17 00:00:00 2001 From: Yu Tian Date: Mon, 10 Feb 2020 12:54:10 +0800 Subject: [PATCH] qcacmn: cdp: Implement API cdp_set_key_sec_type Peer key security type is set in cdp_set_pn_check, this API is called in key install step, but only update Ucast field even if in Mcast key install. This may be set wrongly if Ucast and Mcast security modes are different. Add a new API to set security modes of differ key types separately. Change-Id: Icaa63139d117de75633ca1f81eb618c6b9294b53 CRs-Fixed: 2617461 --- dp/inc/cdp_txrx_cmn.h | 30 ++++++++++++++++ dp/inc/cdp_txrx_ops.h | 6 ++++ dp/wifi3.0/dp_internal.h | 5 +++ dp/wifi3.0/dp_main.c | 1 + dp/wifi3.0/dp_peer.c | 46 +++++++++++++++++++++++++ target_if/crypto/src/target_if_crypto.c | 4 +++ 6 files changed, 92 insertions(+) diff --git a/dp/inc/cdp_txrx_cmn.h b/dp/inc/cdp_txrx_cmn.h index ffc1b940af..06804789c3 100644 --- a/dp/inc/cdp_txrx_cmn.h +++ b/dp/inc/cdp_txrx_cmn.h @@ -1677,6 +1677,36 @@ static inline int cdp_set_pn_check(ol_txrx_soc_handle soc, return 0; } +/** + * cdp_set_key_sec_type(): function to set sec mode of key + * @soc: soc handle + * @vdev_id: id of virtual device + * @peer_mac: mac address of peer + * @sec_type: security type + * #is_unicast: ucast or mcast + */ +static inline int cdp_set_key_sec_type(ol_txrx_soc_handle soc, + uint8_t vdev_id, + uint8_t *peer_mac, + enum cdp_sec_type sec_type, + bool is_unicast) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance:", __func__); + QDF_BUG(0); + return 0; + } + + if (!soc->ops->cmn_drv_ops || + !soc->ops->cmn_drv_ops->set_key_sec_type) + return 0; + + soc->ops->cmn_drv_ops->set_key_sec_type(soc, vdev_id, + peer_mac, sec_type, is_unicast); + return 0; +} + static inline QDF_STATUS cdp_set_key(ol_txrx_soc_handle soc, uint8_t vdev_id, diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 0c84365bdd..56c4e649ac 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -437,6 +437,12 @@ struct cdp_cmn_ops { uint8_t vdev_id, uint8_t *peermac, enum cdp_sec_type sec_type, uint32_t *rx_pn); + + QDF_STATUS(*set_key_sec_type)(struct cdp_soc_t *soc_handle, + uint8_t vdev_id, uint8_t *peermac, + enum cdp_sec_type sec_type, + bool is_unicast); + QDF_STATUS (*update_config_parameters)(struct cdp_soc *psoc, struct cdp_config_params *params); diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index 0766b67362..e1fc51e733 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -1140,6 +1140,11 @@ dp_set_pn_check_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id, uint8_t *peer_mac, enum cdp_sec_type sec_type, uint32_t *rx_pn); +QDF_STATUS +dp_set_key_sec_type_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, enum cdp_sec_type sec_type, + bool is_unicast); + void *dp_get_pdev_for_mac_id(struct dp_soc *soc, uint32_t mac_id); QDF_STATUS diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index a3f81adb35..4f89421128 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -9964,6 +9964,7 @@ static struct cdp_cmn_ops dp_ops_cmn = { .txrx_intr_attach = dp_soc_interrupt_attach_wrapper, .txrx_intr_detach = dp_soc_interrupt_detach, .set_pn_check = dp_set_pn_check_wifi3, + .set_key_sec_type = dp_set_key_sec_type_wifi3, .update_config_parameters = dp_update_config_parameters, /* TODO: Add other functions */ .txrx_data_tx_cb_set = dp_txrx_data_tx_cb_set, diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index a252adcf9a..c1e08926e0 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -3097,6 +3097,52 @@ fail: } +/** + * dp_set_key_sec_type_wifi3() - set security mode of key + * @soc: Datapath soc handle + * @peer_mac: Datapath peer mac address + * @vdev_id: id of atapath vdev + * @vdev: Datapath vdev + * @pdev - data path device instance + * @sec_type - security type + * #is_unicast - key type + * + */ + +QDF_STATUS +dp_set_key_sec_type_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, enum cdp_sec_type sec_type, + bool is_unicast) +{ + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, + peer_mac, 0, vdev_id); + QDF_STATUS status = QDF_STATUS_SUCCESS; + int sec_index; + + if (!peer || peer->delete_in_progress) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s: Peer is NULL!\n", __func__); + status = QDF_STATUS_E_FAILURE; + goto fail; + } + + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, + "key sec spec for peer %pK %pM: %s key of type %d", + peer, + peer->mac_addr.raw, + is_unicast ? "ucast" : "mcast", + sec_type); + + sec_index = is_unicast ? dp_sec_ucast : dp_sec_mcast; + peer->security[sec_index].sec_type = sec_type; + +fail: + if (peer) + dp_peer_unref_delete(peer); + + return status; +} + void dp_rx_sec_ind_handler(struct dp_soc *soc, uint16_t peer_id, enum cdp_sec_type sec_type, int is_unicast, diff --git a/target_if/crypto/src/target_if_crypto.c b/target_if/crypto/src/target_if_crypto.c index 1460ab4043..abeb87fd10 100644 --- a/target_if/crypto/src/target_if_crypto.c +++ b/target_if/crypto/src/target_if_crypto.c @@ -200,6 +200,10 @@ QDF_STATUS target_if_crypto_set_key(struct wlan_objmgr_vdev *vdev, qdf_mem_copy(&pn[0], ¶ms.key_rsc_ctr, sizeof(pn)); cdp_set_pn_check(soc, vdev->vdev_objmgr.vdev_id, req->macaddr, sec_type, pn); + + cdp_set_key_sec_type(soc, vdev->vdev_objmgr.vdev_id, req->macaddr, + sec_type, pairwise); + cdp_set_key(soc, vdev->vdev_objmgr.vdev_id, req->macaddr, pairwise, (uint32_t *)(req->keyval + WLAN_CRYPTO_IV_SIZE + WLAN_CRYPTO_MIC_LEN));