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
This commit is contained in:
Ashish Kumar Dhanotiya 2019-02-26 21:43:32 +05:30 committed by nshrivas
parent 7f548c6986
commit 0213793334
13 changed files with 125 additions and 2 deletions

View File

@ -946,7 +946,7 @@ static void hdd_save_bss_info(struct hdd_adapter *adapter,
} }
/* Cache last connection info */ /* Cache last connection info */
qdf_mem_copy(&hdd_sta_ctx->cache_conn_info, &hdd_sta_ctx->conn_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 #endif
qdf_mem_zero(roam_profile->Keys.KeyLength, CSR_MAX_NUM_KEY); 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 #ifdef FEATURE_WLAN_WAPI
adapter->wapi_info.wapi_auth_mode = WAPI_AUTH_MODE_OPEN; adapter->wapi_info.wapi_auth_mode = WAPI_AUTH_MODE_OPEN;
adapter->wapi_info.wapi_mode = false; 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); hdd_wmm_adapter_clear(adapter);
mac_handle = hdd_ctx->mac_handle; mac_handle = hdd_ctx->mac_handle;
sme_ft_reset(mac_handle, adapter->vdev_id); sme_ft_reset(mac_handle, adapter->vdev_id);
sme_reset_key(mac_handle, adapter->vdev_id);
if (hdd_remove_beacon_filter(adapter) != 0) if (hdd_remove_beacon_filter(adapter) != 0)
hdd_err("hdd_remove_beacon_filter() failed"); hdd_err("hdd_remove_beacon_filter() failed");
@ -3438,6 +3440,8 @@ hdd_association_completion_handler(struct hdd_adapter *adapter,
timeout_reason); timeout_reason);
} }
hdd_clear_roam_profile_ie(adapter); hdd_clear_roam_profile_ie(adapter);
sme_reset_key(hdd_ctx->mac_handle,
adapter->vdev_id);
} else if ((eCSR_ROAM_CANCELLED == roam_status } else if ((eCSR_ROAM_CANCELLED == roam_status
&& !hddDisconInProgress)) { && !hddDisconInProgress)) {
hdd_connect_result(dev, hdd_connect_result(dev,

View File

@ -14597,6 +14597,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
default: default:
hdd_err("Unsupported cipher type: %u", params->cipher); hdd_err("Unsupported cipher type: %u", params->cipher);
qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return -EOPNOTSUPP; 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 a key is already installed, block all subsequent ones */
if (adapter->session.station.ibss_enc_key_installed) { if (adapter->session.station.ibss_enc_key_installed) {
hdd_debug("IBSS key installed already"); hdd_debug("IBSS key installed already");
qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return 0; return 0;
} }
@ -14627,6 +14629,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
if (0 != status) { if (0 != status) {
hdd_err("sme_roam_set_key failed, status: %d", status); hdd_err("sme_roam_set_key failed, status: %d", status);
qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return -EINVAL; return -EINVAL;
} }
/* Save the keys here and call sme_roam_set_key for setting /* 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)); &setKey, sizeof(tCsrRoamSetKey));
adapter->session.station.ibss_enc_key_installed = 1; adapter->session.station.ibss_enc_key_installed = 1;
qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return qdf_status_to_os_return(status); return qdf_status_to_os_return(status);
} }
if ((adapter->device_mode == QDF_SAP_MODE) || 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); adapter->vdev_id, &setKey);
if (status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) { if (status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) {
hdd_debug("Update PreAuth Key success"); hdd_debug("Update PreAuth Key success");
qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return 0; return 0;
} else if (status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) { } else if (status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) {
hdd_err("Update PreAuth Key failed"); hdd_err("Update PreAuth Key failed");
qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return -EINVAL; return -EINVAL;
} }
@ -14711,6 +14717,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
if (0 != status) { if (0 != status) {
hdd_err("sme_roam_set_key failed, status: %d", status); hdd_err("sme_roam_set_key failed, status: %d", status);
qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return -EINVAL; return -EINVAL;
} }
@ -14747,10 +14754,12 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
if (0 != status) { if (0 != status) {
hdd_err("sme_roam_set_key failed for group key (IBSS), returned %d", status); hdd_err("sme_roam_set_key failed for group key (IBSS), returned %d", status);
qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
return -EINVAL; return -EINVAL;
} }
} }
} }
qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
hdd_exit(); hdd_exit();
return 0; return 0;
} }

View File

@ -479,6 +479,8 @@ void lim_cleanup(struct mac_context *mac)
} }
if (mac->lim.gpLimMlmSetKeysReq != NULL) { if (mac->lim.gpLimMlmSetKeysReq != NULL) {
qdf_mem_zero(mac->lim.gpLimMlmSetKeysReq,
sizeof(tLimMlmSetKeysReq));
qdf_mem_free(mac->lim.gpLimMlmSetKeysReq); qdf_mem_free(mac->lim.gpLimMlmSetKeysReq);
mac->lim.gpLimMlmSetKeysReq = NULL; mac->lim.gpLimMlmSetKeysReq = NULL;
} }

View File

@ -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; mlm_set_keys_req = (tLimMlmSetKeysReq *) msg_buf;
if (mac_ctx->lim.gpLimMlmSetKeysReq != NULL) { 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); qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
mac_ctx->lim.gpLimMlmSetKeysReq = NULL; 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); mlm_set_keys_req->sessionId);
if (NULL == session) { if (NULL == session) {
pe_err("session does not exist for given sessionId"); 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); qdf_mem_free(mlm_set_keys_req);
mac_ctx->lim.gpLimMlmSetKeysReq = NULL; mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
return; return;
@ -2025,6 +2030,7 @@ lim_process_mlm_set_keys_req(struct mac_context *mac_ctx, uint32_t *msg_buf)
session->peSessionId); session->peSessionId);
/* Package WMA_SET_BSSKEY_REQ message parameters */ /* Package WMA_SET_BSSKEY_REQ message parameters */
lim_send_set_bss_key_req(mac_ctx, mlm_set_keys_req, session); lim_send_set_bss_key_req(mac_ctx, mlm_set_keys_req, session);
return; return;
} else { } else {
/* /*

View File

@ -2825,6 +2825,7 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx,
sme_session_id); sme_session_id);
if (session_entry == NULL) { if (session_entry == NULL) {
pe_err("session does not exist for given session_id"); pe_err("session does not exist for given session_id");
qdf_mem_zero(msg->bodyptr, sizeof(*set_key_params));
qdf_mem_free(msg->bodyptr); qdf_mem_free(msg->bodyptr);
msg->bodyptr = NULL; msg->bodyptr = NULL;
lim_send_sme_set_context_rsp(mac_ctx, 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 * Free the buffer cached for the global
* mac_ctx->lim.gpLimMlmSetKeysReq * mac_ctx->lim.gpLimMlmSetKeysReq
*/ */
qdf_mem_zero(mac_ctx->lim.gpLimMlmSetKeysReq,
sizeof(tpLimMlmSetKeysReq));
qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq); qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
mac_ctx->lim.gpLimMlmSetKeysReq = NULL; mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
} else { } 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, lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF,
(uint32_t *) &mlm_set_key_cnf); (uint32_t *) &mlm_set_key_cnf);
} }
qdf_mem_zero(msg->bodyptr, sizeof(*set_key_params));
qdf_mem_free(msg->bodyptr); qdf_mem_free(msg->bodyptr);
msg->bodyptr = NULL; msg->bodyptr = NULL;
} }
@ -2920,6 +2924,7 @@ void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac_ctx,
if (session_entry == NULL) { if (session_entry == NULL) {
pe_err("session does not exist for given sessionId [%d]", pe_err("session does not exist for given sessionId [%d]",
session_id); session_id);
qdf_mem_zero(msg->bodyptr, sizeof(tSetBssKeyParams));
qdf_mem_free(msg->bodyptr); qdf_mem_free(msg->bodyptr);
msg->bodyptr = NULL; msg->bodyptr = NULL;
lim_send_sme_set_context_rsp(mac_ctx, set_key_cnf.peer_macaddr, 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 * Free the buffer cached for the
* global mac_ctx->lim.gpLimMlmSetKeysReq * global mac_ctx->lim.gpLimMlmSetKeysReq
*/ */
qdf_mem_zero(mac_ctx->lim.gpLimMlmSetKeysReq,
sizeof(*set_key_req));
qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq); qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
mac_ctx->lim.gpLimMlmSetKeysReq = NULL; mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
} else { } else {
@ -2981,6 +2988,7 @@ void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac_ctx,
&set_key_cnf.peer_macaddr, &set_key_cnf.peer_macaddr,
&((tpSetBssKeyParams)msg->bodyptr)->macaddr); &((tpSetBssKeyParams)msg->bodyptr)->macaddr);
} }
qdf_mem_zero(msg->bodyptr, sizeof(tSetBssKeyParams));
qdf_mem_free(msg->bodyptr); qdf_mem_free(msg->bodyptr);
msg->bodyptr = NULL; msg->bodyptr = NULL;

View File

@ -2575,6 +2575,8 @@ __lim_process_sme_set_context_req(struct mac_context *mac_ctx,
return; return;
qdf_mem_copy(set_context_req, msg_buf, qdf_mem_copy(set_context_req, msg_buf,
sizeof(*set_context_req)); sizeof(*set_context_req));
qdf_mem_zero(msg_buf, sizeof(*set_context_req));
sme_session_id = set_context_req->sessionId; sme_session_id = set_context_req->sessionId;
if ((!lim_is_sme_set_context_req_valid(mac_ctx, set_context_req))) { 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); session_entry, sme_session_id);
} }
end: end:
qdf_mem_zero(set_context_req, sizeof(*set_context_req));
qdf_mem_free(set_context_req); qdf_mem_free(set_context_req);
return; return;
} }

View File

@ -745,6 +745,7 @@ void lim_post_sme_set_keys_cnf(struct mac_context *mac,
&pMlmSetKeysReq->peer_macaddr); &pMlmSetKeysReq->peer_macaddr);
/* Free up buffer allocated for mlmSetKeysReq */ /* Free up buffer allocated for mlmSetKeysReq */
qdf_mem_zero(pMlmSetKeysReq, sizeof(tLimMlmSetKeysReq));
qdf_mem_free(pMlmSetKeysReq); qdf_mem_free(pMlmSetKeysReq);
mac->lim.gpLimMlmSetKeysReq = NULL; 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... */ return; /* Continue after WMA_SET_STAKEY_RSP... */
free_sta_key: free_sta_key:
qdf_mem_zero(pSetStaKeyParams, sizeof(tSetStaKeyParams));
qdf_mem_free(pSetStaKeyParams); qdf_mem_free(pSetStaKeyParams);
fail: fail:
/* Respond to SME with LIM_MLM_SETKEYS_CNF */ /* Respond to SME with LIM_MLM_SETKEYS_CNF */

View File

@ -1042,6 +1042,10 @@ void pe_delete_session(struct mac_context *mac_ctx, struct pe_session *session)
session->valid = false; session->valid = false;
session->mac_ctx = NULL; session->mac_ctx = NULL;
qdf_mem_zero(session->WEPKeyMaterial,
sizeof(session->WEPKeyMaterial));
if (session->access_policy_vendor_ie) if (session->access_policy_vendor_ie)
qdf_mem_free(session->access_policy_vendor_ie); qdf_mem_free(session->access_policy_vendor_ie);

View File

@ -95,6 +95,22 @@ void sme_get_rici_es(mac_handle_t mac_handle, uint32_t sessionId,
* Return: QDF_STATUS * Return: QDF_STATUS
*/ */
QDF_STATUS sme_check_ft_status(mac_handle_t mac_handle, uint32_t session_id); 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_preauth_reassoc_intvl_timer_callback(void *context);
void sme_set_ft_pre_auth_state(mac_handle_t mac_handle, uint32_t sessionId, void sme_set_ft_pre_auth_state(mac_handle_t mac_handle, uint32_t sessionId,
bool state); bool state);

View File

@ -512,6 +512,35 @@ void sme_preauth_reassoc_intvl_timer_callback(void *context)
pUsrCtx->sessionId); 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. */ /* Reset the FT context. */
void sme_ft_reset(mac_handle_t mac_handle, uint32_t sessionId) void sme_ft_reset(mac_handle_t mac_handle, uint32_t sessionId)
{ {

View File

@ -4129,6 +4129,24 @@ static QDF_STATUS csr_roam_get_qos_info_from_bss(struct mac_context *mac,
return status; 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, void csr_set_cfg_privacy(struct mac_context *mac, struct csr_roam_profile *pProfile,
bool fPrivacy) bool fPrivacy)
{ {
@ -16630,6 +16648,8 @@ void csr_cleanup_session(struct mac_context *mac, uint32_t sessionId)
/* Clean up FT related data structures */ /* Clean up FT related data structures */
sme_ft_close(MAC_HANDLE(mac), sessionId); sme_ft_close(MAC_HANDLE(mac), sessionId);
csr_free_connect_bss_desc(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_connect_profile(&pSession->connectedProfile);
csr_roam_free_connected_info(mac, &pSession->connectedInfo); csr_roam_free_connected_info(mac, &pSession->connectedInfo);
qdf_mc_timer_destroy(&pSession->hTimerRoaming); qdf_mc_timer_destroy(&pSession->hTimerRoaming);

View File

@ -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, int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event,
uint32_t len); 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 #endif
/** /**

View File

@ -2573,6 +2573,17 @@ static void wma_handle_set_link_down_rsp(tp_wma_handle wma,
} }
#endif #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 QDF_STATUS
__wma_handle_vdev_stop_rsp(wmi_vdev_stopped_event_fixed_param *resp_event) __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); resp_event->vdev_id);
} }
/* Clear key information */
wma_clear_iface_key(iface);
wma_release_wakelock(&iface->vdev_stop_wakelock); wma_release_wakelock(&iface->vdev_stop_wakelock);
req_msg = wma_find_vdev_req(wma, resp_event->vdev_id, req_msg = wma_find_vdev_req(wma, resp_event->vdev_id,