From 02137933349716cc2c66f095cb923f416d4255b1 Mon Sep 17 00:00:00 2001 From: Ashish Kumar Dhanotiya Date: Tue, 26 Feb 2019 21:43:32 +0530 Subject: [PATCH] qcacld-3.0: Clear PTK, GTK and IGTK keys on sta disconnection Currently PTK, GTK and IGTK keys are not getting cleared on wifi link disconnection from wifi driver memory, which can lead to information disclosure. Clear PTK, GTK and IGTK keys from wifi driver memory to avoid any potential information disclore after wifi is turned off. Change-Id: I309cd7af8d396167e9ec3ef9c6c443e8c08903d8 CRs-fixed: 2396603 --- core/hdd/src/wlan_hdd_assoc.c | 8 +++-- core/hdd/src/wlan_hdd_cfg80211.c | 9 ++++++ core/mac/src/pe/lim/lim_api.c | 2 ++ .../src/pe/lim/lim_process_mlm_req_messages.c | 6 ++++ .../src/pe/lim/lim_process_mlm_rsp_messages.c | 8 +++++ .../src/pe/lim/lim_process_sme_req_messages.c | 3 ++ core/mac/src/pe/lim/lim_security_utils.c | 2 ++ core/mac/src/pe/lim/lim_session.c | 4 +++ core/sme/inc/sme_ft_api.h | 16 ++++++++++ core/sme/src/common/sme_ft_api.c | 29 +++++++++++++++++++ core/sme/src/csr/csr_api_roam.c | 20 +++++++++++++ core/wma/inc/wma_internal.h | 7 +++++ core/wma/src/wma_dev_if.c | 13 +++++++++ 13 files changed, 125 insertions(+), 2 deletions(-) diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index b9b4eaed33c69..64c142fd36d11 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -946,7 +946,7 @@ static void hdd_save_bss_info(struct hdd_adapter *adapter, } /* Cache last connection info */ qdf_mem_copy(&hdd_sta_ctx->cache_conn_info, &hdd_sta_ctx->conn_info, - sizeof(struct hdd_connection_info)); + sizeof(hdd_sta_ctx->cache_conn_info)); } /** @@ -1605,7 +1605,8 @@ static void hdd_clear_roam_profile_ie(struct hdd_adapter *adapter) #endif qdf_mem_zero(roam_profile->Keys.KeyLength, CSR_MAX_NUM_KEY); - + qdf_mem_zero(roam_profile->Keys.KeyMaterial, + sizeof(roam_profile->Keys.KeyMaterial)); #ifdef FEATURE_WLAN_WAPI adapter->wapi_info.wapi_auth_mode = WAPI_AUTH_MODE_OPEN; adapter->wapi_info.wapi_mode = false; @@ -1808,6 +1809,7 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, hdd_wmm_adapter_clear(adapter); mac_handle = hdd_ctx->mac_handle; sme_ft_reset(mac_handle, adapter->vdev_id); + sme_reset_key(mac_handle, adapter->vdev_id); if (hdd_remove_beacon_filter(adapter) != 0) hdd_err("hdd_remove_beacon_filter() failed"); @@ -3438,6 +3440,8 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, timeout_reason); } hdd_clear_roam_profile_ie(adapter); + sme_reset_key(hdd_ctx->mac_handle, + adapter->vdev_id); } else if ((eCSR_ROAM_CANCELLED == roam_status && !hddDisconInProgress)) { hdd_connect_result(dev, diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 9f7e72a3e0644..b381b0c53c587 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -14597,6 +14597,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, default: hdd_err("Unsupported cipher type: %u", params->cipher); + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return -EOPNOTSUPP; } @@ -14617,6 +14618,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, /* if a key is already installed, block all subsequent ones */ if (adapter->session.station.ibss_enc_key_installed) { hdd_debug("IBSS key installed already"); + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return 0; } @@ -14627,6 +14629,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, if (0 != status) { hdd_err("sme_roam_set_key failed, status: %d", status); + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return -EINVAL; } /* Save the keys here and call sme_roam_set_key for setting @@ -14636,6 +14639,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, &setKey, sizeof(tCsrRoamSetKey)); adapter->session.station.ibss_enc_key_installed = 1; + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return qdf_status_to_os_return(status); } if ((adapter->device_mode == QDF_SAP_MODE) || @@ -14698,9 +14702,11 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, adapter->vdev_id, &setKey); if (status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) { hdd_debug("Update PreAuth Key success"); + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return 0; } else if (status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) { hdd_err("Update PreAuth Key failed"); + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return -EINVAL; } @@ -14711,6 +14717,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, if (0 != status) { hdd_err("sme_roam_set_key failed, status: %d", status); + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return -EINVAL; } @@ -14747,10 +14754,12 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, if (0 != status) { hdd_err("sme_roam_set_key failed for group key (IBSS), returned %d", status); + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return -EINVAL; } } } + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); hdd_exit(); return 0; } diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index 782a8ec011fc8..1772bf2512e5f 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -479,6 +479,8 @@ void lim_cleanup(struct mac_context *mac) } if (mac->lim.gpLimMlmSetKeysReq != NULL) { + qdf_mem_zero(mac->lim.gpLimMlmSetKeysReq, + sizeof(tLimMlmSetKeysReq)); qdf_mem_free(mac->lim.gpLimMlmSetKeysReq); mac->lim.gpLimMlmSetKeysReq = NULL; } diff --git a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c index 1be16a666f921..24cd3ea0eef7d 100644 --- a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c @@ -1879,6 +1879,8 @@ lim_process_mlm_set_keys_req(struct mac_context *mac_ctx, uint32_t *msg_buf) mlm_set_keys_req = (tLimMlmSetKeysReq *) msg_buf; if (mac_ctx->lim.gpLimMlmSetKeysReq != NULL) { + qdf_mem_zero(mac_ctx->lim.gpLimMlmSetKeysReq, + sizeof(*mlm_set_keys_req)); qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq); mac_ctx->lim.gpLimMlmSetKeysReq = NULL; } @@ -1888,6 +1890,9 @@ lim_process_mlm_set_keys_req(struct mac_context *mac_ctx, uint32_t *msg_buf) mlm_set_keys_req->sessionId); if (NULL == session) { pe_err("session does not exist for given sessionId"); + qdf_mem_zero(mlm_set_keys_req->key, + sizeof(mlm_set_keys_req->key)); + mlm_set_keys_req->numKeys = 0; qdf_mem_free(mlm_set_keys_req); mac_ctx->lim.gpLimMlmSetKeysReq = NULL; return; @@ -2025,6 +2030,7 @@ lim_process_mlm_set_keys_req(struct mac_context *mac_ctx, uint32_t *msg_buf) session->peSessionId); /* Package WMA_SET_BSSKEY_REQ message parameters */ lim_send_set_bss_key_req(mac_ctx, mlm_set_keys_req, session); + return; } else { /* diff --git a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c index e40bcdd017c3e..c0aafc8ddd7e1 100644 --- a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c @@ -2825,6 +2825,7 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx, sme_session_id); if (session_entry == NULL) { pe_err("session does not exist for given session_id"); + qdf_mem_zero(msg->bodyptr, sizeof(*set_key_params)); qdf_mem_free(msg->bodyptr); msg->bodyptr = NULL; lim_send_sme_set_context_rsp(mac_ctx, @@ -2868,6 +2869,8 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx, * Free the buffer cached for the global * mac_ctx->lim.gpLimMlmSetKeysReq */ + qdf_mem_zero(mac_ctx->lim.gpLimMlmSetKeysReq, + sizeof(tpLimMlmSetKeysReq)); qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq); mac_ctx->lim.gpLimMlmSetKeysReq = NULL; } else { @@ -2879,6 +2882,7 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx, lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF, (uint32_t *) &mlm_set_key_cnf); } + qdf_mem_zero(msg->bodyptr, sizeof(*set_key_params)); qdf_mem_free(msg->bodyptr); msg->bodyptr = NULL; } @@ -2920,6 +2924,7 @@ void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac_ctx, if (session_entry == NULL) { pe_err("session does not exist for given sessionId [%d]", session_id); + qdf_mem_zero(msg->bodyptr, sizeof(tSetBssKeyParams)); qdf_mem_free(msg->bodyptr); msg->bodyptr = NULL; lim_send_sme_set_context_rsp(mac_ctx, set_key_cnf.peer_macaddr, @@ -2974,6 +2979,8 @@ void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac_ctx, * Free the buffer cached for the * global mac_ctx->lim.gpLimMlmSetKeysReq */ + qdf_mem_zero(mac_ctx->lim.gpLimMlmSetKeysReq, + sizeof(*set_key_req)); qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq); mac_ctx->lim.gpLimMlmSetKeysReq = NULL; } else { @@ -2981,6 +2988,7 @@ void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac_ctx, &set_key_cnf.peer_macaddr, &((tpSetBssKeyParams)msg->bodyptr)->macaddr); } + qdf_mem_zero(msg->bodyptr, sizeof(tSetBssKeyParams)); qdf_mem_free(msg->bodyptr); msg->bodyptr = NULL; diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index 2bd0c5043cffe..3b5246208ce05 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -2575,6 +2575,8 @@ __lim_process_sme_set_context_req(struct mac_context *mac_ctx, return; qdf_mem_copy(set_context_req, msg_buf, sizeof(*set_context_req)); + + qdf_mem_zero(msg_buf, sizeof(*set_context_req)); sme_session_id = set_context_req->sessionId; if ((!lim_is_sme_set_context_req_valid(mac_ctx, set_context_req))) { @@ -2678,6 +2680,7 @@ __lim_process_sme_set_context_req(struct mac_context *mac_ctx, session_entry, sme_session_id); } end: + qdf_mem_zero(set_context_req, sizeof(*set_context_req)); qdf_mem_free(set_context_req); return; } diff --git a/core/mac/src/pe/lim/lim_security_utils.c b/core/mac/src/pe/lim/lim_security_utils.c index df7720a8e5fb2..bd5db23ad8253 100644 --- a/core/mac/src/pe/lim/lim_security_utils.c +++ b/core/mac/src/pe/lim/lim_security_utils.c @@ -745,6 +745,7 @@ void lim_post_sme_set_keys_cnf(struct mac_context *mac, &pMlmSetKeysReq->peer_macaddr); /* Free up buffer allocated for mlmSetKeysReq */ + qdf_mem_zero(pMlmSetKeysReq, sizeof(tLimMlmSetKeysReq)); qdf_mem_free(pMlmSetKeysReq); mac->lim.gpLimMlmSetKeysReq = NULL; @@ -1008,6 +1009,7 @@ void lim_send_set_sta_key_req(struct mac_context *mac, return; /* Continue after WMA_SET_STAKEY_RSP... */ free_sta_key: + qdf_mem_zero(pSetStaKeyParams, sizeof(tSetStaKeyParams)); qdf_mem_free(pSetStaKeyParams); fail: /* Respond to SME with LIM_MLM_SETKEYS_CNF */ diff --git a/core/mac/src/pe/lim/lim_session.c b/core/mac/src/pe/lim/lim_session.c index a5008478cc2b4..c7aee542f5ca6 100644 --- a/core/mac/src/pe/lim/lim_session.c +++ b/core/mac/src/pe/lim/lim_session.c @@ -1042,6 +1042,10 @@ void pe_delete_session(struct mac_context *mac_ctx, struct pe_session *session) session->valid = false; session->mac_ctx = NULL; + + qdf_mem_zero(session->WEPKeyMaterial, + sizeof(session->WEPKeyMaterial)); + if (session->access_policy_vendor_ie) qdf_mem_free(session->access_policy_vendor_ie); diff --git a/core/sme/inc/sme_ft_api.h b/core/sme/inc/sme_ft_api.h index a01bc37fe94e0..481783eaf9180 100644 --- a/core/sme/inc/sme_ft_api.h +++ b/core/sme/inc/sme_ft_api.h @@ -95,6 +95,22 @@ void sme_get_rici_es(mac_handle_t mac_handle, uint32_t sessionId, * Return: QDF_STATUS */ QDF_STATUS sme_check_ft_status(mac_handle_t mac_handle, uint32_t session_id); + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/** + * sme_reset_key() -Reset key information + * @mac_handle: MAC handle + * @vdev_id: vdev identifier + * + * Return: None + */ +void sme_reset_key(mac_handle_t mac_handle, uint32_t vdev_id); +#else +static inline void sme_reset_key(mac_handle_t mac_handle, uint32_t vdev_id) +{ +} +#endif + void sme_preauth_reassoc_intvl_timer_callback(void *context); void sme_set_ft_pre_auth_state(mac_handle_t mac_handle, uint32_t sessionId, bool state); diff --git a/core/sme/src/common/sme_ft_api.c b/core/sme/src/common/sme_ft_api.c index a4dc73e380341..da8a0870a0185 100644 --- a/core/sme/src/common/sme_ft_api.c +++ b/core/sme/src/common/sme_ft_api.c @@ -512,6 +512,35 @@ void sme_preauth_reassoc_intvl_timer_callback(void *context) pUsrCtx->sessionId); } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +#ifdef FEATURE_WLAN_ESE +static void sme_reset_esecckm_info(struct csr_roam_session *session) +{ + qdf_mem_zero(&session->eseCckmInfo, sizeof(session->eseCckmInfo)); +} +#else +static void sme_reset_esecckm_info(struct csr_roam_session *session) +{ +} +#endif +void sme_reset_key(mac_handle_t mac_handle, uint32_t vdev_id) +{ + struct mac_context *mac = MAC_CONTEXT(mac_handle); + struct csr_roam_session *session = NULL; + + if (!mac) { + sme_err("mac is NULL"); + return; + } + + session = CSR_GET_SESSION(mac, vdev_id); + if (!session) + return; + qdf_mem_zero(&session->psk_pmk, sizeof(session->psk_pmk)); + session->pmk_len = 0; + sme_reset_esecckm_info(session); +} +#endif /* Reset the FT context. */ void sme_ft_reset(mac_handle_t mac_handle, uint32_t sessionId) { diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 8e22b5acf71fe..4ab041f619710 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -4129,6 +4129,24 @@ static QDF_STATUS csr_roam_get_qos_info_from_bss(struct mac_context *mac, return status; } +static void csr_reset_cfg_privacy(struct mac_context *mac) +{ + uint8_t Key0[MLME_WEP_KEY_LEN_13] = {0}; + uint8_t Key1[MLME_WEP_KEY_LEN_13] = {0}; + uint8_t Key2[MLME_WEP_KEY_LEN_13] = {0}; + uint8_t Key3[MLME_WEP_KEY_LEN_13] = {0}; + struct wlan_mlme_wep_cfg *wep_params = &mac->mlme_cfg->wep_params; + + mlme_set_wep_key(wep_params, MLME_WEP_DEFAULT_KEY_1, Key0, + MLME_WEP_KEY_LEN_13); + mlme_set_wep_key(wep_params, MLME_WEP_DEFAULT_KEY_2, Key1, + MLME_WEP_KEY_LEN_13); + mlme_set_wep_key(wep_params, MLME_WEP_DEFAULT_KEY_3, Key2, + MLME_WEP_KEY_LEN_13); + mlme_set_wep_key(wep_params, MLME_WEP_DEFAULT_KEY_4, Key3, + MLME_WEP_KEY_LEN_13); +} + void csr_set_cfg_privacy(struct mac_context *mac, struct csr_roam_profile *pProfile, bool fPrivacy) { @@ -16630,6 +16648,8 @@ void csr_cleanup_session(struct mac_context *mac, uint32_t sessionId) /* Clean up FT related data structures */ sme_ft_close(MAC_HANDLE(mac), sessionId); csr_free_connect_bss_desc(mac, sessionId); + sme_reset_key(MAC_HANDLE(mac), sessionId); + csr_reset_cfg_privacy(mac); csr_roam_free_connect_profile(&pSession->connectedProfile); csr_roam_free_connected_info(mac, &pSession->connectedInfo); qdf_mc_timer_destroy(&pSession->hTimerRoaming); diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index f7fafce66f002..c29379608333e 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -231,6 +231,13 @@ int wma_mlme_roam_synch_event_handler_cb(void *handle, uint8_t *event, */ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, uint32_t len); +#else +static inline int wma_mlme_roam_synch_event_handler_cb(void *handle, + uint8_t *event, + uint32_t len) +{ + return 0; +} #endif /** diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 2510d198c9682..aa2ee5abc226f 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -2573,6 +2573,17 @@ static void wma_handle_set_link_down_rsp(tp_wma_handle wma, } #endif +#ifdef WLAN_FEATURE_11W +static void wma_clear_iface_key(struct wma_txrx_node *iface) +{ + qdf_mem_zero(&iface->key, sizeof(iface->key)); +} +#else +static void wma_clear_iface_key(struct wma_txrx_node *iface) +{ +} +#endif + QDF_STATUS __wma_handle_vdev_stop_rsp(wmi_vdev_stopped_event_fixed_param *resp_event) { @@ -2610,6 +2621,8 @@ __wma_handle_vdev_stop_rsp(wmi_vdev_stopped_event_fixed_param *resp_event) resp_event->vdev_id); } + /* Clear key information */ + wma_clear_iface_key(iface); wma_release_wakelock(&iface->vdev_stop_wakelock); req_msg = wma_find_vdev_req(wma, resp_event->vdev_id,