Skip to content

Commit

Permalink
wifi: iwlwifi: mvm: Refactor security key update after D3
Browse files Browse the repository at this point in the history
In the D3 resume flow, use two different iterating functions
to go over the old keys and update the new ones

Signed-off-by: Yedidya Benshimol <yedidya.ben.shimol@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230621144844.a2442844c224.I598ed742c7aaa5414702f03f694f2dc0874bc077@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  • Loading branch information
Yedidya Benshimol authored and Johannes Berg committed Jun 21, 2023
1 parent f52a0b4 commit 60555ea
Showing 1 changed file with 42 additions and 40 deletions.
82 changes: 42 additions & 40 deletions drivers/net/wireless/intel/iwlwifi/mvm/d3.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// 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) 2016-2017 Intel Deutschland GmbH
*/
Expand Down Expand Up @@ -1779,18 +1779,17 @@ struct iwl_mvm_d3_gtk_iter_data {
struct iwl_wowlan_status_data *status;
void *last_gtk;
u32 cipher;
bool find_phase, unhandled_cipher;
bool unhandled_cipher;
int num_keys;
};

static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key,
void *_data)
static void iwl_mvm_d3_find_last_keys(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key,
void *_data)
{
struct iwl_mvm_d3_gtk_iter_data *data = _data;
struct iwl_wowlan_status_data *status = data->status;

if (data->unhandled_cipher)
return;
Expand All @@ -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_TKIP:
/* we support these */
data->last_gtk = key;
data->cipher = key->cipher;
break;
default:
/* everything else (even CMAC for MFP) - disconnect from AP */
/* everything else - disconnect from AP */
data->unhandled_cipher = true;
return;
}

data->num_keys++;
}

/*
* pairwise key - update sequence counters only;
* note that this assumes no TDLS sessions are active
*/
if (sta) {
if (data->find_phase)
return;
static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key,
void *_data)
{
struct iwl_mvm_d3_gtk_iter_data *data = _data;
struct iwl_wowlan_status_data *status = data->status;

switch (key->cipher) {
case WLAN_CIPHER_SUITE_CCMP:
case WLAN_CIPHER_SUITE_GCMP:
case WLAN_CIPHER_SUITE_GCMP_256:
if (data->unhandled_cipher)
return;

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);
iwl_mvm_set_aes_ptk_rx_seq(data->mvm, status, sta, key);
break;
case WLAN_CIPHER_SUITE_TKIP:
return;
}
fallthrough;
case WLAN_CIPHER_SUITE_TKIP:
if (sta) {
atomic64_set(&key->tx_pn, status->ptk.tkip.tx_pn);
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 */
return;
if (data->last_gtk == key)
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,
Expand All @@ -1872,9 +1876,8 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
return false;

/* find last GTK that we used initially, if any */
gtkdata.find_phase = true;
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 */
if (gtkdata.unhandled_cipher)
return false;
Expand All @@ -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
* the one that we used
*/
gtkdata.find_phase = false;
ieee80211_iter_keys(mvm->hw, vif,
iwl_mvm_d3_update_keys, &gtkdata);

Expand Down

0 comments on commit 60555ea

Please sign in to comment.