Commit 60555ea4 authored by Yedidya Benshimol's avatar Yedidya Benshimol Committed by Johannes Berg

wifi: iwlwifi: mvm: Refactor security key update after D3

In the D3 resume flow, use two different iterating functions
to go over the old keys and update the new ones
Signed-off-by: default avatarYedidya Benshimol <yedidya.ben.shimol@intel.com>
Signed-off-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230621144844.a2442844c224.I598ed742c7aaa5414702f03f694f2dc0874bc077@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent f52a0b40
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* /*
* Copyright (C) 2012-2014, 2018-2022 Intel Corporation * Copyright (C) 2012-2014, 2018-2023 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH
*/ */
...@@ -1779,18 +1779,17 @@ struct iwl_mvm_d3_gtk_iter_data { ...@@ -1779,18 +1779,17 @@ struct iwl_mvm_d3_gtk_iter_data {
struct iwl_wowlan_status_data *status; struct iwl_wowlan_status_data *status;
void *last_gtk; void *last_gtk;
u32 cipher; u32 cipher;
bool find_phase, unhandled_cipher; bool unhandled_cipher;
int num_keys; int num_keys;
}; };
static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw, static void iwl_mvm_d3_find_last_keys(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
struct ieee80211_key_conf *key, struct ieee80211_key_conf *key,
void *_data) void *_data)
{ {
struct iwl_mvm_d3_gtk_iter_data *data = _data; struct iwl_mvm_d3_gtk_iter_data *data = _data;
struct iwl_wowlan_status_data *status = data->status;
if (data->unhandled_cipher) if (data->unhandled_cipher)
return; return;
...@@ -1805,51 +1804,56 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw, ...@@ -1805,51 +1804,56 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
case WLAN_CIPHER_SUITE_GCMP_256: case WLAN_CIPHER_SUITE_GCMP_256:
case WLAN_CIPHER_SUITE_TKIP: case WLAN_CIPHER_SUITE_TKIP:
/* we support these */ /* we support these */
data->last_gtk = key;
data->cipher = key->cipher;
break; break;
default: default:
/* everything else (even CMAC for MFP) - disconnect from AP */ /* everything else - disconnect from AP */
data->unhandled_cipher = true; data->unhandled_cipher = true;
return; return;
} }
data->num_keys++; data->num_keys++;
}
/* static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
* pairwise key - update sequence counters only; struct ieee80211_vif *vif,
* note that this assumes no TDLS sessions are active struct ieee80211_sta *sta,
*/ struct ieee80211_key_conf *key,
if (sta) { void *_data)
if (data->find_phase) {
return; struct iwl_mvm_d3_gtk_iter_data *data = _data;
struct iwl_wowlan_status_data *status = data->status;
switch (key->cipher) { if (data->unhandled_cipher)
case WLAN_CIPHER_SUITE_CCMP: return;
case WLAN_CIPHER_SUITE_GCMP:
case WLAN_CIPHER_SUITE_GCMP_256: switch (key->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
/* ignore WEP completely, nothing to do */
return;
case WLAN_CIPHER_SUITE_CCMP:
case WLAN_CIPHER_SUITE_GCMP:
case WLAN_CIPHER_SUITE_GCMP_256:
if (sta) {
atomic64_set(&key->tx_pn, status->ptk.aes.tx_pn); atomic64_set(&key->tx_pn, status->ptk.aes.tx_pn);
iwl_mvm_set_aes_ptk_rx_seq(data->mvm, status, sta, key); iwl_mvm_set_aes_ptk_rx_seq(data->mvm, status, sta, key);
break; return;
case WLAN_CIPHER_SUITE_TKIP: }
fallthrough;
case WLAN_CIPHER_SUITE_TKIP:
if (sta) {
atomic64_set(&key->tx_pn, status->ptk.tkip.tx_pn); atomic64_set(&key->tx_pn, status->ptk.tkip.tx_pn);
iwl_mvm_set_key_rx_seq_tids(key, status->ptk.tkip.seq); iwl_mvm_set_key_rx_seq_tids(key, status->ptk.tkip.seq);
break; return;
} }
if (data->status->num_of_gtk_rekeys)
ieee80211_remove_key(key);
/* that's it for this key */ if (data->last_gtk == key)
return; iwl_mvm_set_key_rx_seq(key, data->status, false);
} }
if (data->find_phase) {
data->last_gtk = key;
data->cipher = key->cipher;
return;
}
if (data->status->num_of_gtk_rekeys)
ieee80211_remove_key(key);
if (data->last_gtk == key)
iwl_mvm_set_key_rx_seq(key, data->status, false);
} }
static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
...@@ -1872,9 +1876,8 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, ...@@ -1872,9 +1876,8 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
return false; return false;
/* find last GTK that we used initially, if any */ /* find last GTK that we used initially, if any */
gtkdata.find_phase = true;
ieee80211_iter_keys(mvm->hw, vif, ieee80211_iter_keys(mvm->hw, vif,
iwl_mvm_d3_update_keys, &gtkdata); iwl_mvm_d3_find_last_keys, &gtkdata);
/* not trying to keep connections with MFP/unhandled ciphers */ /* not trying to keep connections with MFP/unhandled ciphers */
if (gtkdata.unhandled_cipher) if (gtkdata.unhandled_cipher)
return false; return false;
...@@ -1887,7 +1890,6 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, ...@@ -1887,7 +1890,6 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
* invalidate all other GTKs that might still exist and update * invalidate all other GTKs that might still exist and update
* the one that we used * the one that we used
*/ */
gtkdata.find_phase = false;
ieee80211_iter_keys(mvm->hw, vif, ieee80211_iter_keys(mvm->hw, vif,
iwl_mvm_d3_update_keys, &gtkdata); iwl_mvm_d3_update_keys, &gtkdata);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment