diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 65804bf3e9..8774bfcd83 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -64,6 +64,7 @@ QDF_STATUS wlan_mlme_get_edca_params(struct wlan_mlme_edca_params *edca_params, /* * mlme_get_wep_key() - get the wep key to process during auth frame + * @vdev: VDEV object for which the wep key is being requested * @wep_params: cfg wep parameters structure * @wep_key_id: default key number * @default_key: default key to be copied @@ -71,7 +72,8 @@ QDF_STATUS wlan_mlme_get_edca_params(struct wlan_mlme_edca_params *edca_params, * * Return QDF_STATUS */ -QDF_STATUS mlme_get_wep_key(struct wlan_mlme_wep_cfg *wep_params, +QDF_STATUS mlme_get_wep_key(struct wlan_objmgr_vdev *vdev, + struct wlan_mlme_wep_cfg *wep_params, enum wep_key_id wep_keyid, uint8_t *default_key, qdf_size_t *key_len); diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index ce2bcad40a..3b1e4cbbdf 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,6 +26,7 @@ #include "wmi_unified.h" #include "wma.h" #include "wma_internal.h" +#include "wlan_crypto_global_api.h" QDF_STATUS wlan_mlme_get_cfg_str(uint8_t *dst, struct mlme_cfg_str *cfg_str, qdf_size_t *len) @@ -2140,7 +2141,36 @@ QDF_STATUS wlan_mlme_get_edca_params(struct wlan_mlme_edca_params *edca_params, return QDF_STATUS_SUCCESS; } -QDF_STATUS mlme_get_wep_key(struct wlan_mlme_wep_cfg *wep_params, +#ifdef CRYPTO_SET_KEY_CONVERGED +QDF_STATUS mlme_get_wep_key(struct wlan_objmgr_vdev *vdev, + struct wlan_mlme_wep_cfg *wep_params, + enum wep_key_id wep_keyid, uint8_t *default_key, + qdf_size_t *key_len) +{ + struct wlan_crypto_key *crypto_key = NULL; + + if (wep_keyid >= WLAN_CRYPTO_MAXKEYIDX) { + mlme_err("Incorrect wep key index %d", wep_keyid); + return QDF_STATUS_E_INVAL; + } + crypto_key = wlan_crypto_get_key(vdev, wep_keyid); + if (crypto_key == NULL) { + mlme_err("Crypto KEY not present"); + return QDF_STATUS_E_INVAL; + } + + if (crypto_key->keylen > WLAN_CRYPTO_KEY_WEP104_LEN) { + mlme_err("Key too large to hold"); + return QDF_STATUS_E_INVAL; + } + *key_len = crypto_key->keylen; + qdf_mem_copy(default_key, &crypto_key->keyval, crypto_key->keylen); + + return QDF_STATUS_SUCCESS; +} +#else +QDF_STATUS mlme_get_wep_key(struct wlan_objmgr_vdev *vdev, + struct wlan_mlme_wep_cfg *wep_params, enum wep_key_id wep_keyid, uint8_t *default_key, qdf_size_t *key_len) { @@ -2176,6 +2206,7 @@ QDF_STATUS mlme_get_wep_key(struct wlan_mlme_wep_cfg *wep_params, mlme_debug("key_id:%d key_len:%zd", wep_keyid, *key_len); return QDF_STATUS_SUCCESS; } +#endif /* CRYPTO_SET_KEY_CONVERGED */ QDF_STATUS mlme_set_wep_key(struct wlan_mlme_wep_cfg *wep_params, enum wep_key_id wep_keyid, uint8_t *key_to_set, diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index ed056ee420..6f21101eaa 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -64,6 +64,8 @@ #include "wlan_hdd_scan.h" #include "wlan_hdd_nud_tracking.h" +#include +#include /* These are needed to recognize WPA and RSN suite types */ #define HDD_WPA_OUI_SIZE 4 #define HDD_RSN_OUI_SIZE 4 @@ -3772,6 +3774,40 @@ hdd_roam_mic_error_indication_handler(struct hdd_adapter *adapter, GFP_KERNEL); } +#ifdef CRYPTO_SET_KEY_CONVERGED +static QDF_STATUS wlan_hdd_set_key_helper(struct hdd_adapter *adapter, + uint32_t *roam_id) +{ + int ret; + struct wlan_objmgr_vdev *vdev; + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return QDF_STATUS_E_FAILURE; + ret = wlan_cfg80211_crypto_add_key(vdev, true, 0); + hdd_objmgr_put_vdev(adapter); + if (ret != 0) { + hdd_err("crypto add key fail, status: %d", ret); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} +#else +static QDF_STATUS wlan_hdd_set_key_helper(struct hdd_adapter *adapter, + uint32_t *roam_id) +{ + struct hdd_station_ctx *sta_ctx = + WLAN_HDD_GET_STATION_CTX_PTR(adapter); + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + + return sme_roam_set_key(hdd_ctx->mac_handle, + adapter->session_id, + &sta_ctx->ibss_enc_key, + roam_id); +} +#endif + /** * roam_roam_connect_status_update_handler() - IBSS connect status update * @adapter: pointer to adapter @@ -3792,6 +3828,7 @@ roam_roam_connect_status_update_handler(struct hdd_adapter *adapter, eCsrRoamResult roamResult) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct wlan_objmgr_vdev *vdev; QDF_STATUS qdf_status; switch (roamResult) { @@ -3853,18 +3890,18 @@ roam_roam_connect_status_update_handler(struct hdd_adapter *adapter, eSIR_TX_RX; qdf_copy_macaddr(&sta_ctx->ibss_enc_key.peerMac, &roam_info->peerMac); + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return QDF_STATUS_E_FAILURE; + wlan_crypto_update_set_key_peer(vdev, true, 0, + &roam_info->peerMac); + hdd_objmgr_put_vdev(adapter); hdd_debug("New peer joined set PTK encType=%d", encr_type); - - qdf_status = - sme_roam_set_key(hdd_ctx->mac_handle, - adapter->session_id, - &sta_ctx->ibss_enc_key, - &roamId); - + qdf_status = wlan_hdd_set_key_helper(adapter, &roamId); if (QDF_STATUS_SUCCESS != qdf_status) { - hdd_err("sme_roam_set_key failed, status: %d", + hdd_err("sme set_key fail status: %d", qdf_status); return QDF_STATUS_E_FAILURE; } diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 6d8a6a8dc9..8db63ecab3 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -133,6 +133,7 @@ #include "wlan_hdd_object_manager.h" #include "nan_ucfg_api.h" #include "wlan_fwol_ucfg_api.h" +#include "wlan_cfg80211_crypto.h" #define g_mode_rates_size (12) #define a_mode_rates_size (8) @@ -13380,7 +13381,7 @@ void wlan_hdd_cfg80211_deregister_frames(struct hdd_adapter *adapter) WNM_NOTIFICATION_FRAME_SIZE); } -#ifdef FEATURE_WLAN_WAPI +#if defined(FEATURE_WLAN_WAPI) && !defined(CRYPTO_SET_KEY_CONVERGED) static void wlan_hdd_cfg80211_set_key_wapi(struct hdd_adapter *adapter, uint8_t key_index, const uint8_t *mac_addr, @@ -14069,6 +14070,215 @@ static int wlan_hdd_change_station(struct wiphy *wiphy, return ret; } +#ifdef CRYPTO_SET_KEY_CONVERGED +#ifdef FEATURE_WLAN_ESE +static bool hdd_is_krk_enc_type(uint32_t cipher_type) +{ + if (cipher_type == WLAN_CIPHER_SUITE_KRK) + return true; + + return false; +} +#else +static bool hdd_is_krk_enc_type(uint32_t cipher_type) +{ + return false; +} +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(WLAN_FEATURE_ROAM_OFFLOAD) +static bool hdd_is_btk_enc_type(uint32_t cipher_type) +{ + if (cipher_type == WLAN_CIPHER_SUITE_BTK) + return true; + + return false; +} +#else +static bool hdd_is_btk_enc_type(uint32_t cipher_type) +{ + return false; +} +#endif +#endif + +#ifdef CRYPTO_SET_KEY_CONVERGED +static int wlan_hdd_add_key_ibss(struct hdd_adapter *adapter, + bool pairwise, u8 key_index, + const u8 *mac_addr, struct key_params *params, + bool *key_already_installed) +{ + struct wlan_objmgr_vdev *vdev; + int errno; + + if (pairwise) + return 0; + /* if a key is already installed, block all subsequent ones */ + if (adapter->session.station.ibss_enc_key_installed) { + hdd_debug("IBSS key installed already"); + *key_already_installed = true; + return 0; + } + /*Set the group key */ + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + errno = wlan_cfg80211_crypto_add_key(vdev, pairwise, key_index); + if (errno) { + hdd_err("add_ibss_key failed, errno: %d", errno); + hdd_objmgr_put_vdev(adapter); + return errno; + } + /* Save the keys here and call set_key for setting + * the PTK after peer joins the IBSS network + */ + wlan_cfg80211_store_key(vdev, key_index, true, mac_addr, params); + hdd_objmgr_put_vdev(adapter); + adapter->session.station.ibss_enc_key_installed = 1; + + return 0; +} + +static int wlan_hdd_add_key_sap(struct hdd_adapter *adapter, + bool pairwise, u8 key_index) +{ + struct wlan_objmgr_vdev *vdev; + int errno = 0; + struct hdd_hostapd_state *hostapd_state = + WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + if (hostapd_state->bss_state == BSS_START) + errno = wlan_cfg80211_crypto_add_key(vdev, pairwise, key_index); + hdd_objmgr_put_vdev(adapter); + + return errno; +} + +static int wlan_hdd_add_key_sta(struct hdd_adapter *adapter, + bool pairwise, u8 key_index, + mac_handle_t mac_handle, bool *ft_mode) +{ + struct wlan_objmgr_vdev *vdev; + struct hdd_station_ctx *sta_ctx = + WLAN_HDD_GET_STATION_CTX_PTR(adapter); + int errno; + QDF_STATUS status; + + if (!pairwise) { + /* set group key */ + if (sta_ctx->roam_info.defer_key_complete) { + hdd_debug("Perform Set key Complete"); + hdd_perform_roam_set_key_complete(adapter); + } + } + /* The supplicant may attempt to set the PTK once + * pre-authentication is done. Save the key in the + * UMAC and include it in the ADD BSS request + */ + status = sme_check_ft_status(mac_handle, adapter->session_id); + if (status == QDF_STATUS_SUCCESS) { + *ft_mode = true; + return 0; + } + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + errno = wlan_cfg80211_crypto_add_key(vdev, pairwise, key_index); + hdd_objmgr_put_vdev(adapter); + if (!errno && adapter->send_mode_change) { + wlan_hdd_send_mode_change_event(); + adapter->send_mode_change = false; + } + + return errno; +} + +static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, bool pairwise, + const u8 *mac_addr, + struct key_params *params) +{ + struct hdd_context *hdd_ctx; + mac_handle_t mac_handle; + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev); + struct wlan_objmgr_vdev *vdev; + bool key_already_installed = false, ft_mode = false; + enum wlan_crypto_cipher_type cipher; + int errno; + + hdd_enter(); + + if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { + hdd_err("Command not allowed in FTM mode"); + return -EINVAL; + } + + if (wlan_hdd_validate_session_id(adapter->session_id)) + return -EINVAL; + + qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_ADD_KEY, + adapter->session_id, params->key_len); + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + errno = wlan_hdd_validate_context(hdd_ctx); + if (errno) + return errno; + + hdd_debug("converged Device_mode %s(%d)", + qdf_opmode_str(adapter->device_mode), + adapter->device_mode); + mac_handle = hdd_ctx->mac_handle; + + if (hdd_is_btk_enc_type(params->cipher)) + return sme_add_key_btk(mac_handle, adapter->session_id, + params->key, params->key_len); + if (hdd_is_krk_enc_type(params->cipher)) + return sme_add_key_krk(mac_handle, adapter->session_id, + params->key, params->key_len); + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + errno = wlan_cfg80211_store_key(vdev, key_index, pairwise, mac_addr, + params); + hdd_objmgr_put_vdev(adapter); + if (errno) + return errno; + switch (adapter->device_mode) { + case QDF_IBSS_MODE: + errno = wlan_hdd_add_key_ibss(adapter, pairwise, key_index, + mac_addr, params, + &key_already_installed); + if (key_already_installed) + return 0; + break; + case QDF_SAP_MODE: + case QDF_P2P_GO_MODE: + errno = wlan_hdd_add_key_sap(adapter, pairwise, key_index); + break; + case QDF_STA_MODE: + case QDF_P2P_CLIENT_MODE: + wlan_hdd_add_key_sta(adapter, pairwise, key_index, + mac_handle, &ft_mode); + if (ft_mode) + return 0; + break; + default: + break; + } + if (!errno) { + cipher = osif_nl_to_crypto_cipher_type(params->cipher); + wma_update_set_key(adapter->session_id, pairwise, key_index, + cipher); + } + hdd_exit(); + + return errno; +} +#else /* !CRYPTO_SET_KEY_CONVERGED */ /* * FUNCTION: __wlan_hdd_cfg80211_add_key * This function is used to initialize the key information @@ -14081,9 +14291,9 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, { struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev); tCsrRoamSetKey setKey; - int status; + int errno; uint32_t roamId = INVALID_ROAM_ID; - QDF_STATUS qdf_ret_status; + QDF_STATUS status; struct hdd_context *hdd_ctx; mac_handle_t mac_handle; @@ -14097,14 +14307,13 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, if (wlan_hdd_validate_session_id(adapter->session_id)) return -EINVAL; - MTRACE(qdf_trace(QDF_MODULE_ID_HDD, - TRACE_CODE_HDD_CFG80211_ADD_KEY, - adapter->session_id, params->key_len)); + qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_ADD_KEY, + adapter->session_id, params->key_len); hdd_ctx = WLAN_HDD_GET_CTX(adapter); - status = wlan_hdd_validate_context(hdd_ctx); + errno = wlan_hdd_validate_context(hdd_ctx); - if (0 != status) - return status; + if (errno) + return errno; hdd_debug("Device_mode %s(%d)", qdf_opmode_str(adapter->device_mode), adapter->device_mode); @@ -14268,7 +14477,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, &setKey, sizeof(tCsrRoamSetKey)); adapter->session.station.ibss_enc_key_installed = 1; - return status; + return qdf_status_to_os_return(status); } if ((adapter->device_mode == QDF_SAP_MODE) || (adapter->device_mode == QDF_P2P_GO_MODE)) { @@ -14326,19 +14535,20 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, * pre-authentication is done. Save the key in the * UMAC and include it in the ADD BSS request */ - qdf_ret_status = sme_ft_update_key(mac_handle, - adapter->session_id, &setKey); - if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) { + status = sme_ft_update_key(mac_handle, + adapter->session_id, &setKey); + if (status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) { hdd_debug("Update PreAuth Key success"); return 0; - } else if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) { + } else if (status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) { hdd_err("Update PreAuth Key failed"); return -EINVAL; } /* issue set key request to SME */ status = sme_roam_set_key(mac_handle, - adapter->session_id, &setKey, &roamId); + adapter->session_id, &setKey, + &roamId); if (0 != status) { hdd_err("sme_roam_set_key failed, status: %d", status); @@ -14385,6 +14595,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, hdd_exit(); return 0; } +#endif /* CRYPTO_SET_KEY_CONVERGED */ static int wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, @@ -14487,9 +14698,8 @@ static int __wlan_hdd_cfg80211_get_key(struct wiphy *wiphy, break; } - MTRACE(qdf_trace(QDF_MODULE_ID_HDD, - TRACE_CODE_HDD_CFG80211_GET_KEY, - adapter->session_id, params.cipher)); + qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_GET_KEY, + adapter->session_id, params.cipher); params.key_len = roam_profile->Keys.KeyLength[key_index]; params.seq_len = 0; @@ -14577,6 +14787,7 @@ static int wlan_hdd_cfg80211_del_key(struct wiphy *wiphy, return ret; } +#ifndef CRYPTO_SET_KEY_CONVERGED #ifdef FEATURE_WLAN_WAPI static bool hdd_is_wapi_enc_type(eCsrEncryptionType ucEncryptionType) { @@ -14591,7 +14802,72 @@ static bool hdd_is_wapi_enc_type(eCsrEncryptionType ucEncryptionType) return false; } #endif +#endif +#ifdef CRYPTO_SET_KEY_CONVERGED +static int __wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool unicast, bool multicast) +{ + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev); + struct hdd_context *hdd_ctx; + struct qdf_mac_addr bssid = QDF_MAC_ADDR_BCAST_INIT; + struct hdd_station_ctx *sta_ctx; + struct wlan_crypto_key *crypto_key; + int ret; + QDF_STATUS status; + + if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { + hdd_err("Command not allowed in FTM mode"); + return -EINVAL; + } + + if (wlan_hdd_validate_session_id(adapter->session_id)) + return -EINVAL; + + qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY, + adapter->session_id, key_index); + + hdd_debug("Device_mode %s(%d) key_index = %d", + qdf_opmode_str(adapter->device_mode), + adapter->device_mode, key_index); + + if (CSR_MAX_NUM_KEY <= key_index) { + hdd_err("Invalid key index: %d", key_index); + return -EINVAL; + } + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + ret = wlan_hdd_validate_context(hdd_ctx); + + if (0 != ret) + return ret; + crypto_key = wlan_crypto_get_key(adapter->vdev, key_index); + hdd_debug("unicast %d, cipher %d", unicast, crypto_key->cipher_type); + if (crypto_key->cipher_type != WLAN_CRYPTO_CIPHER_WEP) + return 0; + sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + if (unicast) + status = + wlan_cfg80211_set_default_key(adapter->vdev, key_index, + &sta_ctx->conn_info.bssId); + else + status = wlan_cfg80211_set_default_key(adapter->vdev, key_index, + &bssid); + if (QDF_STATUS_SUCCESS != status) { + hdd_err("ret fail status %d", ret); + return -EINVAL; + } + if ((adapter->device_mode == QDF_STA_MODE) || + (adapter->device_mode == QDF_P2P_CLIENT_MODE)) { + ret = wlan_cfg80211_crypto_add_key(adapter->vdev, unicast, + key_index); + } + + return ret; +} +#else /* * FUNCTION: __wlan_hdd_cfg80211_set_default_key * This function is used to set the default tx key index @@ -14616,9 +14892,8 @@ static int __wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy, if (wlan_hdd_validate_session_id(adapter->session_id)) return -EINVAL; - MTRACE(qdf_trace(QDF_MODULE_ID_HDD, - TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY, - adapter->session_id, key_index)); + qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY, + adapter->session_id, key_index); hdd_debug("Device_mode %s(%d) key_index = %d", qdf_opmode_str(adapter->device_mode), @@ -14744,6 +15019,7 @@ static int __wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy, hdd_exit(); return status; } +#endif static int wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, diff --git a/core/mac/src/pe/lim/lim_process_auth_frame.c b/core/mac/src/pe/lim/lim_process_auth_frame.c index 8b12a66322..34dda3945e 100644 --- a/core/mac/src/pe/lim/lim_process_auth_frame.c +++ b/core/mac/src/pe/lim/lim_process_auth_frame.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -757,7 +757,8 @@ static void lim_process_auth_frame_type2(struct mac_context *mac_ctx, qdf_mem_copy(defaultkey, key_ptr->key, key_ptr->keyLength); } else { - qdf_status = mlme_get_wep_key(wep_params, + qdf_status = mlme_get_wep_key(pe_session->vdev, + wep_params, (MLME_WEP_DEFAULT_KEY_1 + key_id), defaultkey, &val); @@ -1363,7 +1364,8 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, key_ptr->keyLength); val = key_ptr->keyLength; } else { - qdf_status = mlme_get_wep_key(wep_params, + qdf_status = mlme_get_wep_key(pe_session->vdev, + wep_params, (MLME_WEP_DEFAULT_KEY_1 + key_id), defaultkey, &val); 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 e380437736..c0e7fafdf4 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -2808,6 +2808,7 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx, struct pe_session *session_entry; uint16_t key_len; uint16_t result_status; + tSetStaKeyParams *set_key_params; SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true); qdf_mem_set((void *)&mlm_set_key_cnf, sizeof(tLimMlmSetKeysCnf), 0); @@ -2815,8 +2816,9 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx, pe_err("msg bodyptr is NULL"); return; } - session_id = ((tpSetStaKeyParams) msg->bodyptr)->sessionId; - sme_session_id = ((tpSetBssKeyParams) msg->bodyptr)->smesessionId; + set_key_params = msg->bodyptr; + session_id = set_key_params->sessionId; + sme_session_id = set_key_params->smesessionId; session_entry = pe_find_session_by_session_id(mac_ctx, session_id); if (session_entry == NULL) { pe_err("session does not exist for given session_id"); @@ -2828,17 +2830,21 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx, sme_session_id, 0); return; } - if (eLIM_MLM_WT_SET_STA_KEY_STATE != session_entry->limMlmState) { - pe_err("Received unexpected [Mesg Id - %d] in state %X", - msg->type, session_entry->limMlmState); - resp_reqd = 0; - } else { - mlm_set_key_cnf.resultCode = - (uint16_t)(((tpSetStaKeyParams) msg->bodyptr)->status); + result_status = set_key_params->status; + if (!lim_is_set_key_req_converged()) { + if (eLIM_MLM_WT_SET_STA_KEY_STATE != + session_entry->limMlmState) { + pe_err("Received unexpected [Mesg Id - %d] in state %X", + msg->type, session_entry->limMlmState); + resp_reqd = 0; + } else { + mlm_set_key_cnf.resultCode = result_status; + } + /* Restore MLME state */ + session_entry->limMlmState = session_entry->limPrevMlmState; } - result_status = (uint16_t)(((tpSetStaKeyParams) msg->bodyptr)->status); - key_len = ((tpSetStaKeyParams)msg->bodyptr)->key[0].keyLength; + key_len = set_key_params->key[0].keyLength; if (result_status == eSIR_SME_SUCCESS && key_len) mlm_set_key_cnf.key_len_nonzero = true; @@ -2846,10 +2852,6 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx, mlm_set_key_cnf.key_len_nonzero = false; - qdf_mem_free(msg->bodyptr); - msg->bodyptr = NULL; - /* Restore MLME state */ - session_entry->limMlmState = session_entry->limPrevMlmState; MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session_entry->peSessionId, session_entry->limMlmState)); if (resp_reqd) { @@ -2865,11 +2867,17 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx, */ qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq); mac_ctx->lim.gpLimMlmSetKeysReq = NULL; + } else { + lim_copy_set_key_req_mac_addr( + &mlm_set_key_cnf.peer_macaddr, + &set_key_params->macaddr); } mlm_set_key_cnf.sessionId = session_id; lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF, (uint32_t *) &mlm_set_key_cnf); } + qdf_mem_free(msg->bodyptr); + msg->bodyptr = NULL; } /** @@ -2932,21 +2940,19 @@ void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac_ctx, else set_key_cnf.key_len_nonzero = false; - /* Validate MLME state */ - if (eLIM_MLM_WT_SET_BSS_KEY_STATE != session_entry->limMlmState && - eLIM_MLM_WT_SET_STA_BCASTKEY_STATE != - session_entry->limMlmState) { - pe_err("Received unexpected [Mesg Id - %d] in state %X", - msg->type, session_entry->limMlmState); - } else { - set_key_cnf.resultCode = result_status; + if (!lim_is_set_key_req_converged()) { + if (eLIM_MLM_WT_SET_BSS_KEY_STATE != + session_entry->limMlmState && + eLIM_MLM_WT_SET_STA_BCASTKEY_STATE != + session_entry->limMlmState) { + pe_err("Received unexpected [Mesg Id - %d] in state %X", + msg->type, session_entry->limMlmState); + } else { + set_key_cnf.resultCode = result_status; + } + session_entry->limMlmState = session_entry->limPrevMlmState; } - qdf_mem_free(msg->bodyptr); - msg->bodyptr = NULL; - /* Restore MLME state */ - session_entry->limMlmState = session_entry->limPrevMlmState; - MTRACE(mac_trace (mac_ctx, TRACE_CODE_MLM_STATE, session_entry->peSessionId, session_entry->limMlmState)); @@ -2964,7 +2970,14 @@ void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac_ctx, */ qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq); mac_ctx->lim.gpLimMlmSetKeysReq = NULL; + } else { + lim_copy_set_key_req_mac_addr( + &set_key_cnf.peer_macaddr, + &((tpSetStaKeyParams)msg->bodyptr)->macaddr); } + qdf_mem_free(msg->bodyptr); + msg->bodyptr = NULL; + lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF, (uint32_t *) &set_key_cnf); } diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h index 5a0db20be8..3dc47b0685 100644 --- a/core/mac/src/pe/lim/lim_utils.h +++ b/core/mac/src/pe/lim/lim_utils.h @@ -1660,4 +1660,26 @@ QDF_STATUS lim_ap_mlme_vdev_start_req_failed(struct vdev_mlme_obj *vdev_mlme, #endif +#ifdef CRYPTO_SET_KEY_CONVERGED +static inline bool lim_is_set_key_req_converged(void) +{ + return true; +} + +static inline void lim_copy_set_key_req_mac_addr(struct qdf_mac_addr *dst, + struct qdf_mac_addr *src) +{ + qdf_copy_macaddr(dst, src); +} +#else +static inline bool lim_is_set_key_req_converged(void) +{ + return false; +} + +static inline void lim_copy_set_key_req_mac_addr(struct qdf_mac_addr *dst, + struct qdf_mac_addr *src) +{ +} +#endif #endif /* __LIM_UTILS_H */ diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index d7c1f5a7de..a5b4086dcc 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -50,45 +50,14 @@ #include "wlan_reg_services_api.h" #include #include +#include +#include -/*---------------------------------------------------------------------------- - * Preprocessor Definitions and Constants - * -------------------------------------------------------------------------*/ #define SAP_DEBUG - -/*---------------------------------------------------------------------------- - * Type Declarations - * -------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- - * Global Data Definitions - * -------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- - * External declarations for global context - * -------------------------------------------------------------------------*/ -/* No! Get this from CDS. */ -/* The main per-Physical Link (per WLAN association) context. */ static struct sap_context *gp_sap_ctx[SAP_MAX_NUM_SESSION]; static qdf_atomic_t sap_ctx_ref_count[SAP_MAX_NUM_SESSION]; - -/*---------------------------------------------------------------------------- - * Static Variable Definitions - * -------------------------------------------------------------------------*/ static qdf_mutex_t sap_context_lock; -/*---------------------------------------------------------------------------- - * Static Function Declarations and Definitions - * -------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- - * Externalized Function Definitions - * -------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- - * Function Declarations and Documentation - * -------------------------------------------------------------------------*/ - /** * wlansap_global_init() - Initialize SAP globals * @@ -1401,19 +1370,28 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sapContext, return QDF_STATUS_SUCCESS; } -QDF_STATUS wlansap_set_key_sta(struct sap_context *sap_ctx, - tCsrRoamSetKey *key_info) +#ifdef CRYPTO_SET_KEY_CONVERGED +static QDF_STATUS wlan_sap_set_key_helper(struct sap_context *sap_ctx, + tCsrRoamSetKey *set_key_info) +{ + struct wlan_crypto_key *crypto_key; + + crypto_key = wlan_crypto_get_key(sap_ctx->vdev, 0); + if (!crypto_key) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + "Crypto KEY is NULL"); + return QDF_STATUS_E_FAILURE; + } + + return ucfg_crypto_set_key_req(sap_ctx->vdev, crypto_key, true); +} +#else +static QDF_STATUS wlan_sap_set_key_helper(struct sap_context *sap_ctx, + tCsrRoamSetKey *set_key_info) { uint32_t roam_id = INVALID_ROAM_ID; struct mac_context *mac; - if (!sap_ctx) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s: Invalid SAP pointer", - __func__); - return QDF_STATUS_E_FAULT; - } - mac = sap_get_mac_context(); if (!mac) { QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context"); @@ -1421,7 +1399,27 @@ QDF_STATUS wlansap_set_key_sta(struct sap_context *sap_ctx, } return sme_roam_set_key(MAC_HANDLE(mac), sap_ctx->sessionId, - key_info, &roam_id); + set_key_info, &roam_id); +} +#endif + +QDF_STATUS wlansap_set_key_sta(struct sap_context *sap_ctx, + tCsrRoamSetKey *set_key_info) +{ + QDF_STATUS qdf_status; + + if (!sap_ctx) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer", + __func__); + return QDF_STATUS_E_FAULT; + } + + qdf_status = wlan_sap_set_key_helper(sap_ctx, set_key_info); + if (qdf_status != QDF_STATUS_SUCCESS) + qdf_status = QDF_STATUS_E_FAULT; + + return qdf_status; } QDF_STATUS wlan_sap_getstation_ie_information(struct sap_context *sap_ctx, diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index af97360dd3..afc38ace56 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -2927,6 +2927,44 @@ sme_get_sta_cxn_info(mac_handle_t mac_handle, uint32_t session_id, } #endif +#ifdef FEATURE_WLAN_ESE +/** + * sme_add_key_btk() - Add BTK key + * @mac_handle: MAC handle + * @session_id: SME session identifier + * @key: key material + * @key_len: length of the key + * + * Return: 0 on success and negative value for failure + */ +int sme_add_key_btk(mac_handle_t mac_handle, uint8_t session_id, + const uint8_t *key, const int key_len); +/** + * sme_add_key_krk() - Add KRK key + * @mac_handle: MAC handle + * @session_id: SME session identifier + * @key: key material + * @key_len: length of the key + * + * Return: 0 on success and negative value for failure + */ +int sme_add_key_krk(mac_handle_t mac_handle, uint8_t session_id, + const uint8_t *key, const int key_len); + +#else +static inline int sme_add_key_btk(mac_handle_t mac_handle, uint8_t session_id, + const uint8_t *key, const int key_len) +{ + return 0; +} + +static inline int sme_add_key_krk(mac_handle_t mac_handle, uint8_t session_id, + const uint8_t *key, const int key_len) +{ + return 0; +} +#endif + /** * sme_find_session_by_bssid() - checks whether has session * with given bssid diff --git a/core/sme/inc/sme_ft_api.h b/core/sme/inc/sme_ft_api.h index e5674a2188..a01bc37fe9 100644 --- a/core/sme/inc/sme_ft_api.h +++ b/core/sme/inc/sme_ft_api.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2016, 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, 2018, 2019 The Linux Foundation. + * All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -86,6 +87,14 @@ void sme_get_ft_pre_auth_response(mac_handle_t mac_handle, uint32_t sessionId, void sme_get_rici_es(mac_handle_t mac_handle, uint32_t sessionId, uint8_t *ric_ies, uint32_t ric_ies_ip_len, uint32_t *ric_ies_length); +/** + * sme_check_ft_status() - Check for key wait status in FT mode + * @mac_handle: MAC handle + * @session_id: vdev identifier + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_check_ft_status(mac_handle_t mac_handle, uint32_t session_id); 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_api.c b/core/sme/src/common/sme_api.c index 312271053f..bca38f1210 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -6242,6 +6242,63 @@ QDF_STATUS sme_config_fast_roaming(mac_handle_t mac_handle, uint8_t session_id, return QDF_STATUS_SUCCESS; } +#ifdef FEATURE_WLAN_ESE +int sme_add_key_krk(mac_handle_t mac_handle, uint8_t session_id, + const uint8_t *key, const int key_len) +{ + struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); + struct csr_roam_session *session; + + if (key_len < SIR_KRK_KEY_LEN) { + sme_warn("Invalid KRK keylength [= %d]", key_len); + return -EINVAL; + } + + if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { + sme_err("incorrect session/vdev ID"); + return -EINVAL; + } + + session = CSR_GET_SESSION(mac_ctx, session_id); + + qdf_mem_copy(session->eseCckmInfo.krk, key, SIR_KRK_KEY_LEN); + session->eseCckmInfo.reassoc_req_num = 1; + session->eseCckmInfo.krk_plumbed = true; + + return 0; +} + +int sme_add_key_btk(mac_handle_t mac_handle, uint8_t session_id, + const uint8_t *key, const int key_len) +{ + struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); + struct csr_roam_session *session; + + if (key_len < SIR_BTK_KEY_LEN) { + sme_warn("Invalid BTK keylength [= %d]", key_len); + return -EINVAL; + } + + if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { + sme_err("incorrect session/vdev ID"); + return -EINVAL; + } + + session = CSR_GET_SESSION(mac_ctx, session_id); + + qdf_mem_copy(session->eseCckmInfo.btk, key, SIR_BTK_KEY_LEN); + /* + * KRK and BTK are updated by upper layer back to back. Send + * updated KRK and BTK together to FW here. + */ + csr_roam_offload_scan(mac_ctx, session_id, + ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_ROAM_PSK_PMK_CHANGED); + + return 0; +} +#endif + /** * sme_stop_roaming() - Stop roaming for a given sessionId * This is a synchronous call diff --git a/core/sme/src/common/sme_ft_api.c b/core/sme/src/common/sme_ft_api.c index 9897db8119..2c1ab19e26 100644 --- a/core/sme/src/common/sme_ft_api.c +++ b/core/sme/src/common/sme_ft_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -307,6 +307,46 @@ void sme_set_ftptk_state(mac_handle_t mac_handle, uint32_t sessionId, pSession->ftSmeContext.setFTPTKState = state; } +QDF_STATUS sme_check_ft_status(mac_handle_t mac_handle, uint32_t session_id) +{ + struct mac_context *mac = MAC_CONTEXT(mac_handle); + struct csr_roam_session *session = CSR_GET_SESSION(mac, session_id); + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + if (!session) { + sme_err("pSession is NULL"); + return QDF_STATUS_E_FAILURE; + } + + status = sme_acquire_global_lock(&mac->sme); + if (!(QDF_IS_STATUS_SUCCESS(status))) + return QDF_STATUS_E_FAILURE; + + sme_debug("FT update key is received in state %d", + session->ftSmeContext.FTState); + + /* Global Station FT State */ + switch (session->ftSmeContext.FTState) { + case eFT_SET_KEY_WAIT: + if (sme_get_ft_pre_auth_state(mac_handle, session_id) == true) { + sme_set_ft_pre_auth_state(mac_handle, session_id, + false); + session->ftSmeContext.FTState = eFT_START_READY; + sme_debug("state changed to %d status %d", + session->ftSmeContext.FTState, status); + sme_release_global_lock(&mac->sme); + return QDF_STATUS_SUCCESS; + } + default: + sme_debug("Unhandled state:%d", session->ftSmeContext.FTState); + status = QDF_STATUS_E_FAILURE; + break; + } + sme_release_global_lock(&mac->sme); + + return status; +} + QDF_STATUS sme_ft_update_key(mac_handle_t mac_handle, uint32_t sessionId, tCsrRoamSetKey *pFTKeyInfo) { diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index e61421caac..ed03ac7939 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -60,6 +60,8 @@ #include "cfg_mlme.h" #include "cfg_ucfg_api.h" #include "wlan_mlme_api.h" +#include "wlan_mlme_public_struct.h" +#include #define MAX_PWR_FCC_CHAN_12 8 #define MAX_PWR_FCC_CHAN_13 2 @@ -6550,7 +6552,7 @@ static void csr_roam_process_start_bss_success(struct mac_context *mac_ctx, */ if (!CSR_IS_IBSS(session->pCurRoamProfile)) { /* NO keys. these key parameters don't matter */ - csr_roam_issue_set_context_req(mac_ctx, + csr_roam_issue_set_context_req_helper(mac_ctx, session_id, profile->negotiatedMCEncryptionType, bss_desc, &bcast_mac, false, @@ -6735,7 +6737,7 @@ static void csr_process_fils_join_rsp(struct mac_context *mac_ctx, goto process_fils_join_rsp_fail; } - status = csr_roam_issue_set_context_req(mac_ctx, session_id, + status = csr_roam_issue_set_context_req_helper(mac_ctx, session_id, profile->negotiatedMCEncryptionType, bss_desc, &bcast_mac, true, false, eSIR_RX_ONLY, 2, @@ -6746,7 +6748,7 @@ static void csr_process_fils_join_rsp(struct mac_context *mac_ctx, goto process_fils_join_rsp_fail; } - status = csr_roam_issue_set_context_req(mac_ctx, session_id, + status = csr_roam_issue_set_context_req_helper(mac_ctx, session_id, profile->negotiatedUCEncryptionType, bss_desc, &(bss_desc->bssId), true, true, eSIR_TX_RX, 0, @@ -6925,7 +6927,7 @@ static void csr_roam_process_join_res(struct mac_context *mac_ctx, * the Unicast STA context */ if (!QDF_IS_STATUS_SUCCESS( - csr_roam_issue_set_context_req(mac_ctx, + csr_roam_issue_set_context_req_helper(mac_ctx, session_id, profile->negotiatedUCEncryptionType, bss_desc, &(bss_desc->bssId), @@ -6941,7 +6943,8 @@ static void csr_roam_process_join_res(struct mac_context *mac_ctx, * to establish the Broadcast STA context * NO keys. these key parameters don't matter */ - csr_roam_issue_set_context_req(mac_ctx, session_id, + csr_roam_issue_set_context_req_helper(mac_ctx, + session_id, profile->negotiatedMCEncryptionType, bss_desc, &bcast_mac, false, false, eSIR_TX_RX, 0, 0, NULL, 0); @@ -9732,15 +9735,69 @@ void csr_roam_joined_state_msg_processor(struct mac_context *mac, void *pMsgBuf) } } -QDF_STATUS csr_roam_issue_set_context_req(struct mac_context *mac, - uint32_t sessionId, - eCsrEncryptionType EncryptType, - tSirBssDescription *pBssDescription, - tSirMacAddr *bssId, bool addKey, - bool fUnicast, - tAniKeyDirection aniKeyDirection, - uint8_t keyId, uint16_t keyLength, - uint8_t *pKey, uint8_t paeRole) +#ifdef CRYPTO_SET_KEY_CONVERGED +static QDF_STATUS csr_roam_issue_set_context_req(struct mac_context *mac_ctx, + uint32_t session_id, + bool add_key, bool unicast, + uint8_t key_idx) +{ + enum wlan_crypto_cipher_type cipher; + struct wlan_crypto_key *crypto_key; + uint8_t wep_key_idx = 0; + struct wlan_objmgr_vdev *vdev; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, session_id, + WLAN_LEGACY_MAC_ID); + if (!vdev) { + sme_err("VDEV object not found for session_id %d", session_id); + return QDF_STATUS_E_INVAL; + } + cipher = wlan_crypto_get_cipher(vdev, unicast, key_idx); + if (cipher == WLAN_CRYPTO_CIPHER_WEP_40 || + cipher == WLAN_CRYPTO_CIPHER_WEP_104) { + wep_key_idx = wlan_crypto_get_default_key_idx(vdev, !unicast); + crypto_key = wlan_crypto_get_key(vdev, wep_key_idx); + } else { + /* TODO: Add code for storing FILS keys in case of add_key */ + crypto_key = wlan_crypto_get_key(vdev, key_idx); + } + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + + sme_debug("session:%d, cipher:%d, ucast:%d, idx:%d, wep:%d, add:%d", + session_id, cipher, unicast, key_idx, wep_key_idx, add_key); + if (cipher != WLAN_CRYPTO_CIPHER_NONE || + cipher != WLAN_CRYPTO_CIPHER_WEP_40 || + cipher != WLAN_CRYPTO_CIPHER_WEP_104 || + !add_key) + return QDF_STATUS_E_INVAL; + + return ucfg_crypto_set_key_req(vdev, crypto_key, unicast); +} + +QDF_STATUS csr_roam_issue_set_context_req_helper( + struct mac_context *mac_ctx, + uint32_t session_id, + eCsrEncryptionType encr_type, + tSirBssDescription *bss_descr, + tSirMacAddr *bssid, bool addkey, + bool unicast, + tAniKeyDirection key_direction, + uint8_t key_id, uint16_t key_length, + uint8_t *key, uint8_t pae_role) +{ + return csr_roam_issue_set_context_req(mac_ctx, session_id, addkey, + unicast, key_id); +} + +#else +static QDF_STATUS +csr_roam_issue_set_context_req(struct mac_context *mac, uint32_t sessionId, + eCsrEncryptionType EncryptType, + tSirBssDescription *pBssDescription, + tSirMacAddr *bssId, bool addKey, bool fUnicast, + tAniKeyDirection aniKeyDirection, uint8_t keyId, + uint16_t keyLength, uint8_t *pKey, + uint8_t paeRole) { QDF_STATUS status = QDF_STATUS_SUCCESS; tAniEdType edType; @@ -9778,6 +9835,24 @@ QDF_STATUS csr_roam_issue_set_context_req(struct mac_context *mac, return status; } +QDF_STATUS csr_roam_issue_set_context_req_helper( + struct mac_context *mac_ctx, + uint32_t session_id, + eCsrEncryptionType encr_type, + tSirBssDescription *bss_descr, + tSirMacAddr *bssid, bool addkey, + bool unicast, + tAniKeyDirection key_direction, + uint8_t key_id, uint16_t key_length, + uint8_t *key, uint8_t pae_role) +{ + return csr_roam_issue_set_context_req(mac_ctx, session_id, encr_type, + bss_descr, bssid, addkey, + unicast, key_direction, key_id, + key_length, key, pae_role); +} +#endif + /** * csr_update_key_cmd() - update key info in set key command * @mac_ctx: mac global context @@ -10594,11 +10669,13 @@ csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) CSR_IS_ENC_TYPE_STATIC( session->pCurRoamProfile->negotiatedUCEncryptionType)) { /* NO keys... these key parameters don't matter. */ - csr_roam_issue_set_context_req(mac_ctx, sessionId, - session->pCurRoamProfile->negotiatedUCEncryptionType, - session->pConnectBssDesc, - &(roam_info_ptr->peerMac.bytes), - false, true, eSIR_TX_RX, 0, 0, NULL, 0); + csr_roam_issue_set_context_req_helper(mac_ctx, + sessionId, + session->pCurRoamProfile-> + negotiatedUCEncryptionType, + session->pConnectBssDesc, + &roam_info_ptr->peerMac.bytes, + false, true, eSIR_TX_RX, 0, 0, NULL, 0); roam_info_ptr->fAuthRequired = false; } else { roam_info_ptr->fAuthRequired = true; @@ -11236,7 +11313,7 @@ csr_roam_chk_lnk_wm_status_change_ntf(struct mac_context *mac_ctx, if ((eCSR_ENCRYPT_TYPE_NONE == session->connectedProfile.EncryptionType)) { - csr_roam_issue_set_context_req(mac_ctx, + csr_roam_issue_set_context_req_helper(mac_ctx, sessionId, session->connectedProfile.EncryptionType, session->pConnectBssDesc, @@ -11385,7 +11462,7 @@ csr_roam_chk_lnk_ibss_new_peer_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ if ((eCSR_ENCRYPT_TYPE_NONE == session->connectedProfile.EncryptionType)) { /* NO keys. these key parameters don't matter */ - csr_roam_issue_set_context_req(mac_ctx, sessionId, + csr_roam_issue_set_context_req_helper(mac_ctx, sessionId, session->connectedProfile.EncryptionType, session->pConnectBssDesc, &pIbssPeerInd->peer_addr.bytes, diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index 8d9236efb2..d7e5555c31 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -246,15 +246,17 @@ QDF_STATUS csr_roam_issue_reassoc(struct mac_context *mac, uint32_t sessionId, bool fImediate); void csr_roam_complete(struct mac_context *mac, enum csr_roamcomplete_result Result, void *Context, uint8_t session_id); -QDF_STATUS csr_roam_issue_set_context_req(struct mac_context *mac, - uint32_t sessionId, - eCsrEncryptionType EncryptType, - tSirBssDescription *pBssDescription, - tSirMacAddr *bssId, bool addKey, - bool fUnicast, - tAniKeyDirection aniKeyDirection, - uint8_t keyId, uint16_t keyLength, - uint8_t *pKey, uint8_t paeRole); +QDF_STATUS +csr_roam_issue_set_context_req_helper(struct mac_context *mac, + uint32_t session_id, + eCsrEncryptionType encr_type, + tSirBssDescription *bss_descr, + tSirMacAddr *bssid, bool addkey, + bool unicast, + tAniKeyDirection key_direction, + uint8_t key_id, uint16_t key_length, + uint8_t *key, uint8_t pae_role); + QDF_STATUS csr_roam_process_disassoc_deauth(struct mac_context *mac, tSmeCmd *pCommand, bool fDisassoc, bool fMICFailure); diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 53266bd5e0..df34bce0f9 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -2579,4 +2579,28 @@ 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_update_set_key() - Update WMA layer for set key + * @session_id: vdev session identifier + * @pairwise: denotes if it is pairwise or group key + * @key_index: Key Index + * @cipher_type: cipher type being used for the encryption/decryption + * + * Return: None + */ +void wma_update_set_key(uint8_t session_id, bool pairwise, + uint8_t key_index, + enum wlan_crypto_cipher_type cipher_type); +#endif + +/** + * wma_get_igtk() - Get the IGTK that was stored in the session earlier + * @iface: Interface for which the key is being requested + * @key_len: key length + * + * Return: Pointer to the key + */ +uint8_t *wma_get_igtk(struct wma_txrx_node *iface, uint16_t *key_len); + #endif diff --git a/core/wma/inc/wma_if.h b/core/wma/inc/wma_if.h index 8016d73cde..15ea3aba20 100644 --- a/core/wma/inc/wma_if.h +++ b/core/wma/inc/wma_if.h @@ -349,6 +349,7 @@ typedef struct { * @status: status * @sessionId: session id * @sendRsp: send response + * @macaddr: MAC address of the peer * * This is used by PE to configure the key information on a given station. * When the secType is WEP40 or WEP104, the defWEPIdx is used to locate @@ -366,6 +367,7 @@ typedef struct { QDF_STATUS status; uint8_t sessionId; uint8_t sendRsp; + struct qdf_mac_addr macaddr; } tSetStaKeyParams, *tpSetStaKeyParams; /** @@ -660,6 +662,7 @@ typedef struct sSendProbeRespParams { * @smesessionId: sme session id * @status: return status of command * @sessionId: PE session id + * @macaddr: MAC address of the peer */ typedef struct { uint8_t bssIdx; @@ -670,6 +673,7 @@ typedef struct { uint8_t smesessionId; QDF_STATUS status; uint8_t sessionId; + struct qdf_mac_addr macaddr; } tSetBssKeyParams, *tpSetBssKeyParams; /** diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 988e848216..25548e87a6 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -735,14 +735,43 @@ void wma_update_rts_params(tp_wma_handle wma, uint32_t value); void wma_update_frag_params(tp_wma_handle wma, uint32_t value); -void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info); - void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma, uint8_t vdev_id, int8_t peer_num_delta); +#ifdef CRYPTO_SET_KEY_CONVERGED +static inline void wma_set_stakey(tp_wma_handle wma_handle, + tpSetStaKeyParams key_info) +{ +} + +static inline void wma_set_bsskey(tp_wma_handle wma_handle, + tpSetBssKeyParams key_info) +{ +} +#else +/** + * wma_set_stakey() - set encryption key + * @wma_handle: wma handle + * @key_info: station key info + * + * This function sets encryption key for WEP/WPA/WPA2 + * encryption mode in firmware and send response to upper layer. + * + * Return: none + */ void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info); +/** + * wma_set_bsskey() - set encryption key to fw. + * @wma_handle: wma handle + * @key_info: key info + * + * Return: none + */ +void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info); +#endif + QDF_STATUS wma_process_update_edca_param_req(WMA_HANDLE handle, tEdcaParams *edca_params); diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index 512b813e07..0d56ddcde6 100644 --- a/core/wma/src/wma_data.c +++ b/core/wma/src/wma_data.c @@ -78,6 +78,7 @@ #include #include "wlan_lmac_if_api.h" #include +#include struct wma_search_rate { int32_t rate; @@ -2367,6 +2368,29 @@ static void wma_update_tx_send_params(struct tx_send_params *tx_param, tx_param->preamble_type); } +#ifdef CRYPTO_SET_KEY_CONVERGED +uint8_t *wma_get_igtk(struct wma_txrx_node *iface, uint16_t *key_len) +{ + struct wlan_crypto_key *crypto_key; + + crypto_key = wlan_crypto_get_key(iface->vdev, WMA_IGTK_KEY_INDEX_4); + if (!crypto_key) { + wma_err("IGTK not found"); + *key_len = 0; + return NULL; + } + *key_len = crypto_key->keylen; + + return &crypto_key->keyval[0]; +} +#else +uint8_t *wma_get_igtk(struct wma_txrx_node *iface, uint16_t *key_len) +{ + *key_len = iface->key.key_length; + return iface->key.key; +} +#endif + QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, eFrameType frmType, eFrameTxDir txDir, uint8_t tid, wma_tx_dwnld_comp_callback tx_frm_download_comp_cb, @@ -2403,6 +2427,8 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, void *mac_addr; bool is_5g = false; uint8_t pdev_id; + uint8_t *igtk; + uint16_t key_len; if (NULL == wma_handle) { WMA_LOGE("wma_handle is NULL"); @@ -2530,13 +2556,18 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, qdf_mem_copy(pFrame, wh, sizeof(*wh)); qdf_mem_copy(pFrame + sizeof(*wh), pData + sizeof(*wh), frmLen - sizeof(*wh)); - if (!cds_attach_mmie(iface->key.key, + igtk = wma_get_igtk(iface, &key_len); + if (!igtk) { + wma_alert("IGTK not present"); + cds_packet_free((void *)tx_frame); + goto error; + } + if (!cds_attach_mmie(igtk, iface->key.key_id[0].ipn, WMA_IGTK_KEY_INDEX_4, pFrame, pFrame + newFrmLen, newFrmLen)) { - WMA_LOGP("%s: Failed to attach MMIE at the end of frame", - __func__); + wma_alert("Failed to attach MMIE"); /* Free the original packet memory */ cds_packet_free((void *)tx_frame); goto error; diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index 17c310b364..816b63a3a8 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -68,6 +68,7 @@ #ifdef WLAN_FEATURE_NAN #include "target_if_nan.h" #endif +#include #ifndef ARRAY_LENGTH #define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0])) @@ -5631,6 +5632,99 @@ int wma_vdev_obss_detection_info_handler(void *handle, uint8_t *event, return 0; } +#ifdef CRYPTO_SET_KEY_CONVERGED +static void wma_send_set_key_rsp(uint8_t session_id, bool pairwise, + uint8_t key_index) +{ + tSetStaKeyParams *key_info_uc; + tSetBssKeyParams *key_info_mc; + struct wlan_crypto_key *crypto_key; + struct wlan_objmgr_vdev *vdev; + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + + if (!wma) { + wma_err("WMA context does not exist"); + return; + } + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc, + session_id, + WLAN_LEGACY_WMA_ID); + if (!vdev) { + wma_err("VDEV object not found"); + return; + } + crypto_key = wlan_crypto_get_key(vdev, key_index); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); + if (!crypto_key) { + wma_err("crypto_key not found"); + return; + } + + if (pairwise) { + key_info_uc = qdf_mem_malloc(sizeof(*key_info_uc)); + if (!key_info_uc) + return; + key_info_uc->sessionId = session_id; + key_info_uc->smesessionId = session_id; + key_info_uc->status = QDF_STATUS_SUCCESS; + key_info_uc->key[0].keyLength = crypto_key->keylen; + qdf_mem_copy(&key_info_uc->macaddr, &crypto_key->macaddr, + QDF_MAC_ADDR_SIZE); + wma_send_msg_high_priority(wma, WMA_SET_STAKEY_RSP, + key_info_uc, 0); + } else { + key_info_mc = qdf_mem_malloc(sizeof(*key_info_mc)); + if (!key_info_mc) + return; + key_info_mc->sessionId = session_id; + key_info_mc->smesessionId = session_id; + key_info_mc->status = QDF_STATUS_SUCCESS; + key_info_mc->key[0].keyLength = crypto_key->keylen; + qdf_mem_copy(&key_info_mc->macaddr, &crypto_key->macaddr, + QDF_MAC_ADDR_SIZE); + wma_send_msg_high_priority(wma, WMA_SET_BSSKEY_RSP, + key_info_mc, 0); + } +} + +static void wma_reset_ipn(struct wma_txrx_node *iface, uint8_t key_index) +{ + if (key_index == WMA_IGTK_KEY_INDEX_4 || + key_index == WMA_IGTK_KEY_INDEX_5) + qdf_mem_zero(iface->key.key_id[key_index - + WMA_IGTK_KEY_INDEX_4].ipn, + CMAC_IPN_LEN); +} + +void wma_update_set_key(uint8_t session_id, bool pairwise, + uint8_t key_index, + enum wlan_crypto_cipher_type cipher_type) +{ + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + struct wma_txrx_node *iface; + + if (!wma) { + wma_err("Invalid WMA context"); + return; + } + iface = &wma->interfaces[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"); + wma_release_wakelock(&iface->vdev_set_key_wakelock); + } + if (iface) + iface->is_waiting_for_key = false; + + wma_send_set_key_rsp(session_id, pairwise, key_index); +} +#endif /* CRYPTO_SET_KEY_CONVERGED */ + int wma_vdev_bss_color_collision_info_handler(void *handle, uint8_t *event, uint32_t len) diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 09b3d43360..4486022dde 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -77,6 +77,8 @@ #include "cfg_mlme_sta.h" #include "wlan_mlme_api.h" #include "wmi_unified_bcn_api.h" +#include + /** * wma_send_bcn_buf_ll() - prepare and send beacon buffer to fw for LL * @wma: wma handle @@ -1729,12 +1731,14 @@ void wma_update_frag_params(tp_wma_handle wma, uint32_t value) } } +#ifndef CRYPTO_SET_KEY_CONVERGED /** * wma_read_cfg_wepkey() - fill key_info for WEP key * @wma_handle: wma handle * @key_info: key_info ptr * @def_key_idx: default key index * @num_keys: number of keys + * @vdev: vdev pointer * * This function reads WEP keys from cfg and fills * up key_info. @@ -1743,7 +1747,8 @@ void wma_update_frag_params(tp_wma_handle wma, uint32_t value) */ static void wma_read_cfg_wepkey(tp_wma_handle wma_handle, tSirKeys *key_info, uint32_t *def_key_idx, - uint8_t *num_keys) + uint8_t *num_keys, + struct wlan_objmgr_vdev *vdev) { QDF_STATUS status; qdf_size_t val = SIR_MAC_KEY_LENGTH; @@ -1756,7 +1761,7 @@ static void wma_read_cfg_wepkey(tp_wma_handle wma_handle, *def_key_idx = mac_ctx->mlme_cfg->wep_params.wep_default_key_id; for (i = 0, j = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; i++) { - status = mlme_get_wep_key(&mac_ctx->mlme_cfg->wep_params, + status = mlme_get_wep_key(vdev, &mac_ctx->mlme_cfg->wep_params, (MLME_WEP_DEFAULT_KEY_1 + i), key_info[j].key, &val); if (QDF_IS_STATUS_ERROR(status)) { @@ -1769,6 +1774,7 @@ static void wma_read_cfg_wepkey(tp_wma_handle wma_handle, } *num_keys = j; } +#endif #ifdef FEATURE_WLAN_WAPI #define WPI_IV_LEN 16 @@ -1851,6 +1857,7 @@ static inline void wma_fill_in_wapi_key_params( #endif #endif +#ifndef CRYPTO_SET_KEY_CONVERGED /** * wma_skip_bip_key_set() - skip the BIP key step or not * @wma_handle: wma handle @@ -1935,12 +1942,7 @@ static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle, #endif params.key_txmic_len = 0; params.key_rxmic_len = 0; - params.key_rsc_counter = qdf_mem_malloc(sizeof(uint64_t)); - if (!params.key_rsc_counter) { - WMA_LOGE(FL("can't allocate memory for key_rsc_counter")); - return QDF_STATUS_E_NOMEM; - } - qdf_mem_copy(params.key_rsc_counter, + qdf_mem_copy(¶ms.key_rsc_ctr, &key_params->key_rsc[0], sizeof(uint64_t)); params.key_flags = 0; if (key_params->unicast) @@ -2063,7 +2065,7 @@ static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle, WMA_LOGD("unicast %d peer_mac %pM def_key_idx %d", key_params->unicast, key_params->peer_mac, key_params->def_key_idx); - WMA_LOGD("keyrsc param %llu", *(params.key_rsc_counter)); + WMA_LOGD("keyrsc param %llu", params.key_rsc_ctr); /* * To prevent from any replay-attack, PN number provided by @@ -2112,17 +2114,113 @@ static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle, iface->is_waiting_for_key = false; end: - qdf_mem_free(params.key_rsc_counter); return status; } +#endif + +#ifdef QCA_IBSS_SUPPORT +/** + * wma_calc_ibss_heart_beat_timer() - calculate IBSS heart beat timer + * @peer_num: number of peers + * + * Return: heart beat timer value + */ +static uint16_t wma_calc_ibss_heart_beat_timer(int16_t peer_num) +{ + /* heart beat timer value look-up table */ + /* entry index : (the number of currently connected peers) - 1 + * entry value : the heart time threshold value in seconds for + * detecting ibss peer departure + */ + static const uint16_t heart_beat_timer[MAX_PEERS] = { + 4, 4, 4, 4, 4, 4, 4, 4, + 8, 8, 8, 8, 8, 8, 8, 8, + 12, 12, 12, 12, 12, 12, 12, 12, + 16, 16, 16, 16, 16, 16, 16, 16 + }; + + if (peer_num < 1 || peer_num > MAX_PEERS) + return 0; + + return heart_beat_timer[peer_num - 1]; +} /** - * wma_set_bsskey() - set encryption key to fw. - * @wma_handle: wma handle - * @key_info: key info + * wma_adjust_ibss_heart_beat_timer() - set ibss heart beat timer in fw. + * @wma: wma handle + * @vdev_id: vdev id + * @peer_num_delta: peer number delta value * * Return: none */ +void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma, + uint8_t vdev_id, + int8_t peer_num_delta) +{ + struct cdp_vdev *vdev; + int16_t new_peer_num; + uint16_t new_timer_value_sec; + uint32_t new_timer_value_ms; + QDF_STATUS status; + void *soc = cds_get_context(QDF_MODULE_ID_SOC); + + if (peer_num_delta != 1 && peer_num_delta != -1) { + WMA_LOGE("Invalid peer_num_delta value %d", peer_num_delta); + return; + } + + vdev = wma_find_vdev_by_id(wma, vdev_id); + if (!vdev) { + WMA_LOGE("vdev not found : vdev_id %d", vdev_id); + return; + } + + /* adjust peer numbers */ + new_peer_num = cdp_peer_update_ibss_add_peer_num_of_vdev(soc, vdev, + peer_num_delta + ); + if (OL_TXRX_INVALID_NUM_PEERS == new_peer_num) { + WMA_LOGE("new peer num %d out of valid boundary", new_peer_num); + return; + } + + /* reset timer value if all peers departed */ + if (new_peer_num == 0) { + cdp_set_ibss_vdev_heart_beat_timer(soc, vdev, 0); + return; + } + + /* calculate new timer value */ + new_timer_value_sec = wma_calc_ibss_heart_beat_timer(new_peer_num); + if (new_timer_value_sec == 0) { + WMA_LOGE("timer value %d is invalid for peer number %d", + new_timer_value_sec, new_peer_num); + return; + } + if (new_timer_value_sec == + cdp_set_ibss_vdev_heart_beat_timer(soc, vdev, + new_timer_value_sec)) { + WMA_LOGD("timer value %d stays same, no need to notify target", + new_timer_value_sec); + return; + } + + new_timer_value_ms = ((uint32_t)new_timer_value_sec) * 1000; + + status = wma_vdev_set_param(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS, + new_timer_value_ms); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("Failed to set IBSS link monitoring timer value"); + return; + } + + WMA_LOGD("Set IBSS link monitor timer: peer_num = %d timer_value = %d", + new_peer_num, new_timer_value_ms); +} +#endif /* QCA_IBSS_SUPPORT */ + +#ifndef CRYPTO_SET_KEY_CONVERGED void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info) { struct wma_set_key_params key_params; @@ -2133,6 +2231,7 @@ void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info) struct cdp_vdev *txrx_vdev; uint8_t *mac_addr; void *soc = cds_get_context(QDF_MODULE_ID_SOC); + struct wlan_objmgr_vdev *vdev; WMA_LOGD("BSS key setup"); txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId); @@ -2184,8 +2283,13 @@ void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info) if (key_info->numKeys == 0 && (key_info->encType == eSIR_ED_WEP40 || key_info->encType == eSIR_ED_WEP104)) { + vdev = + wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc, + key_info->smesessionId, + WLAN_LEGACY_WMA_ID); wma_read_cfg_wepkey(wma_handle, key_info->key, - &def_key_idx, &key_info->numKeys); + &def_key_idx, &key_info->numKeys, vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); } else if ((key_info->encType == eSIR_ED_WEP40) || (key_info->encType == eSIR_ED_WEP104)) { struct wma_txrx_node *intf = @@ -2246,108 +2350,6 @@ out: (void *)key_info, 0); } -#ifdef QCA_IBSS_SUPPORT -/** - * wma_calc_ibss_heart_beat_timer() - calculate IBSS heart beat timer - * @peer_num: number of peers - * - * Return: heart beat timer value - */ -static uint16_t wma_calc_ibss_heart_beat_timer(int16_t peer_num) -{ - /* heart beat timer value look-up table */ - /* entry index : (the number of currently connected peers) - 1 - * entry value : the heart time threshold value in seconds for - * detecting ibss peer departure - */ - static const uint16_t heart_beat_timer[MAX_PEERS] = { - 4, 4, 4, 4, 4, 4, 4, 4, - 8, 8, 8, 8, 8, 8, 8, 8, - 12, 12, 12, 12, 12, 12, 12, 12, - 16, 16, 16, 16, 16, 16, 16, 16 - }; - - if (peer_num < 1 || peer_num > MAX_PEERS) - return 0; - - return heart_beat_timer[peer_num - 1]; - -} - -/** - * wma_adjust_ibss_heart_beat_timer() - set ibss heart beat timer in fw. - * @wma: wma handle - * @vdev_id: vdev id - * @peer_num_delta: peer number delta value - * - * Return: none - */ -void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma, - uint8_t vdev_id, - int8_t peer_num_delta) -{ - struct cdp_vdev *vdev; - int16_t new_peer_num; - uint16_t new_timer_value_sec; - uint32_t new_timer_value_ms; - QDF_STATUS status; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - - if (peer_num_delta != 1 && peer_num_delta != -1) { - WMA_LOGE("Invalid peer_num_delta value %d", peer_num_delta); - return; - } - - vdev = wma_find_vdev_by_id(wma, vdev_id); - if (!vdev) { - WMA_LOGE("vdev not found : vdev_id %d", vdev_id); - return; - } - - /* adjust peer numbers */ - new_peer_num = cdp_peer_update_ibss_add_peer_num_of_vdev(soc, - vdev, peer_num_delta); - if (OL_TXRX_INVALID_NUM_PEERS == new_peer_num) { - WMA_LOGE("new peer num %d out of valid boundary", new_peer_num); - return; - } - - /* reset timer value if all peers departed */ - if (new_peer_num == 0) { - cdp_set_ibss_vdev_heart_beat_timer(soc, vdev, 0); - return; - } - - /* calculate new timer value */ - new_timer_value_sec = wma_calc_ibss_heart_beat_timer(new_peer_num); - if (new_timer_value_sec == 0) { - WMA_LOGE("timer value %d is invalid for peer number %d", - new_timer_value_sec, new_peer_num); - return; - } - if (new_timer_value_sec == - cdp_set_ibss_vdev_heart_beat_timer(soc, - vdev, new_timer_value_sec)) { - WMA_LOGD("timer value %d stays same, no need to notify target", - new_timer_value_sec); - return; - } - - new_timer_value_ms = ((uint32_t) new_timer_value_sec) * 1000; - - status = wma_vdev_set_param(wma->wmi_handle, vdev_id, - WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS, - new_timer_value_ms); - if (QDF_IS_STATUS_ERROR(status)) { - WMA_LOGE("Failed to set IBSS link monitoring timer value"); - return; - } - - WMA_LOGD("Set IBSS link monitor timer: peer_num = %d timer_value = %d", - new_peer_num, new_timer_value_ms); -} - -#endif /* QCA_IBSS_SUPPORT */ /** * wma_set_ibsskey_helper() - cached IBSS key in wma handle * @wma_handle: wma handle @@ -2367,6 +2369,7 @@ static void wma_set_ibsskey_helper(tp_wma_handle wma_handle, struct cdp_vdev *txrx_vdev; int opmode; void *soc = cds_get_context(QDF_MODULE_ID_SOC); + struct wlan_objmgr_vdev *vdev; WMA_LOGD("BSS key setup for peer"); txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId); @@ -2391,8 +2394,13 @@ static void wma_set_ibsskey_helper(tp_wma_handle wma_handle, if (key_info->numKeys == 0 && (key_info->encType == eSIR_ED_WEP40 || key_info->encType == eSIR_ED_WEP104)) { + vdev = + wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc, + key_info->smesessionId, + WLAN_LEGACY_WMA_ID); wma_read_cfg_wepkey(wma_handle, key_info->key, - &def_key_idx, &key_info->numKeys); + &def_key_idx, &key_info->numKeys, vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); } else if ((key_info->encType == eSIR_ED_WEP40) || (key_info->encType == eSIR_ED_WEP104)) { struct wma_txrx_node *intf = @@ -2434,16 +2442,6 @@ static void wma_set_ibsskey_helper(tp_wma_handle wma_handle, } } -/** - * wma_set_stakey() - set encryption key - * @wma_handle: wma handle - * @key_info: station key info - * - * This function sets encryption key for WEP/WPA/WPA2 - * encryption mode in firmware and send response to upper layer. - * - * Return: none - */ void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info) { int32_t i; @@ -2456,6 +2454,7 @@ void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info) uint32_t def_key_idx = 0; int opmode; void *soc = cds_get_context(QDF_MODULE_ID_SOC); + struct wlan_objmgr_vdev *vdev; WMA_LOGD("STA key setup"); @@ -2488,8 +2487,13 @@ void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info) (key_info->encType == eSIR_ED_WEP40 || key_info->encType == eSIR_ED_WEP104) && opmode != wlan_op_mode_ap) { + vdev = + wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc, + key_info->smesessionId, + WLAN_LEGACY_WMA_ID); wma_read_cfg_wepkey(wma_handle, key_info->key, - &def_key_idx, &num_keys); + &def_key_idx, &num_keys, vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); key_info->defWEPIdx = def_key_idx; } else { num_keys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; @@ -2568,6 +2572,7 @@ out: wma_send_msg_high_priority(wma_handle, WMA_SET_STAKEY_RSP, (void *)key_info, 0); } +#endif /** * wma_process_update_edca_param_req() - update EDCA params @@ -3729,6 +3734,8 @@ int wma_process_bip(tp_wma_handle wma_handle, uint16_t mmie_size; uint16_t key_id; uint8_t *efrm; + uint8_t *igtk; + uint16_t key_len; efrm = qdf_nbuf_data(wbuf) + qdf_nbuf_len(wbuf); @@ -3756,6 +3763,7 @@ int wma_process_bip(tp_wma_handle wma_handle, WMA_LOGD(FL("key_cipher %d key_id %d"), iface->key.key_cipher, key_id); + igtk = wma_get_igtk(iface, &key_len); switch (iface->key.key_cipher) { case WMI_CIPHER_AES_CMAC: if (wmi_service_enabled(wma_handle->wmi_handle, @@ -3767,9 +3775,10 @@ int wma_process_bip(tp_wma_handle wma_handle, */ qdf_nbuf_trim_tail(wbuf, cds_get_mmie_size()); } else { - if (cds_is_mmie_valid(iface->key.key, - iface->key.key_id[key_id - WMA_IGTK_KEY_INDEX_4].ipn, - (uint8_t *) wh, efrm)) { + if (cds_is_mmie_valid(igtk, iface->key.key_id[ + key_id - + WMA_IGTK_KEY_INDEX_4].ipn, + (uint8_t *)wh, efrm)) { WMA_LOGD(FL("Protected BC/MC frame MMIE validation successful")); /* Remove MMIE */ qdf_nbuf_trim_tail(wbuf, cds_get_mmie_size()); @@ -3791,9 +3800,9 @@ int wma_process_bip(tp_wma_handle wma_handle, WMA_LOGD(FL("Trim GMAC MMIE")); qdf_nbuf_trim_tail(wbuf, cds_get_gmac_mmie_size()); } else { - if (cds_is_gmac_mmie_valid(iface->key.key, + if (cds_is_gmac_mmie_valid(igtk, iface->key.key_id[key_id - WMA_IGTK_KEY_INDEX_4].ipn, - (uint8_t *) wh, efrm, iface->key.key_length)) { + (uint8_t *) wh, efrm, key_len)) { WMA_LOGD(FL("Protected BC/MC frame GMAC MMIE validation successful")); /* Remove MMIE */ qdf_nbuf_trim_tail(wbuf,