aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-07-07 16:28:01 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-07-08 11:11:19 -0400
commit523b02ea23b175dd3e46e3daf1bc9354376640a3 (patch)
treea11f69f05cdfb457a42b2866e33e73937c35ec1e /drivers/net
parent397915c30731340ee3f348d1be597b22467acbdf (diff)
mac80211: fix TKIP races, make API easier to use
Our current TKIP code races against itself on TX since we can process multiple packets at the same time on different ACs, but they all share the TX context for TKIP. This can lead to bad IVs etc. Also, the crypto offload helper code just obtains the P1K/P2K from the cache, and can update it as well, but there's no guarantee that packets are really processed in order. To fix these issues, first introduce a spinlock that will protect the IV16/IV32 values in the TX context. This first step makes sure that we don't assign the same IV multiple times or get confused in other ways. Secondly, change the way the P1K cache works. I add a field "p1k_iv32" that stores the value of the IV32 when the P1K was last recomputed, and if different from the last time, then a new P1K is recomputed. This can cause the P1K computation to flip back and forth if packets are processed out of order. All this also happens under the new spinlock. Finally, because there are argument differences, split up the ieee80211_get_tkip_key() API into ieee80211_get_tkip_p1k() and ieee80211_get_tkip_p2k() and give them the correct arguments. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/b43/xmit.c3
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-4965-tx.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c3
3 files changed, 3 insertions, 6 deletions
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 488b898418a..82bcf759513 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -323,8 +323,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
323 /* we give the phase1key and iv16 here, the key is stored in 323 /* we give the phase1key and iv16 here, the key is stored in
324 * shm. With that the hardware can do phase 2 and encryption. 324 * shm. With that the hardware can do phase 2 and encryption.
325 */ 325 */
326 ieee80211_get_tkip_key(info->control.hw_key, skb_frag, 326 ieee80211_get_tkip_p1k(info->control.hw_key, skb_frag, phase1key);
327 IEEE80211_TKIP_P1_KEY, (u8*)phase1key);
328 /* phase1key is in host endian. Copy to little-endian txhdr->iv. */ 327 /* phase1key is in host endian. Copy to little-endian txhdr->iv. */
329 for (i = 0; i < 5; i++) { 328 for (i = 0; i < 5; i++) {
330 txhdr->iv[i * 2 + 0] = phase1key[i]; 329 txhdr->iv[i * 2 + 0] = phase1key[i];
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
index 79ac081832f..ac4f64de136 100644
--- a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
+++ b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
@@ -240,8 +240,7 @@ static void iwl4965_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
240 240
241 case WLAN_CIPHER_SUITE_TKIP: 241 case WLAN_CIPHER_SUITE_TKIP:
242 tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; 242 tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
243 ieee80211_get_tkip_key(keyconf, skb_frag, 243 ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key);
244 IEEE80211_TKIP_P2_KEY, tx_cmd->key);
245 IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n"); 244 IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
246 break; 245 break;
247 246
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index c05a8d9fbd2..a87e95728b1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -497,8 +497,7 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
497 497
498 case WLAN_CIPHER_SUITE_TKIP: 498 case WLAN_CIPHER_SUITE_TKIP:
499 tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; 499 tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
500 ieee80211_get_tkip_key(keyconf, skb_frag, 500 ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key);
501 IEEE80211_TKIP_P2_KEY, tx_cmd->key);
502 IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n"); 501 IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
503 break; 502 break;
504 503