aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-4965.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2008-04-17 19:03:36 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-07 15:02:11 -0400
commit3ec47732a0be038f15a0b8d852a4e4ff9c5b0196 (patch)
tree2cb45a6582df77a571554850152256df611ce094 /drivers/net/wireless/iwlwifi/iwl-4965.c
parentc6adbd2158fee972adcc6232de5e2ef375f1f782 (diff)
iwlwifi: HW crypto acceleration fixes
This patch fixes several issues in security: 1) the uCode doesn't know about TKIP-MMIC failure, if uCode set RX_RES_STATUS_BAD_ICV_MIC, it means ICV failure: drop the packet silently. 2) do not allocate room in the key table of the uCode is the set_key call is a replacement of an old key 3) check the keyidx of the key in the uCode before removing it upon disable_key call Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-4965.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 69a355bbb97a..ddcd1b232549 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2871,6 +2871,53 @@ static void iwl_update_rx_stats(struct iwl_priv *priv, u16 fc, u16 len)
2871 priv->rx_stats[idx].bytes += len; 2871 priv->rx_stats[idx].bytes += len;
2872} 2872}
2873 2873
2874/*
2875 * returns non-zero if packet should be dropped
2876 */
2877static int iwl4965_set_decrypted_flag(struct iwl_priv *priv,
2878 struct ieee80211_hdr *hdr,
2879 u32 decrypt_res,
2880 struct ieee80211_rx_status *stats)
2881{
2882 u16 fc = le16_to_cpu(hdr->frame_control);
2883
2884 if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
2885 return 0;
2886
2887 if (!(fc & IEEE80211_FCTL_PROTECTED))
2888 return 0;
2889
2890 IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res);
2891 switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) {
2892 case RX_RES_STATUS_SEC_TYPE_TKIP:
2893 /* The uCode has got a bad phase 1 Key, pushes the packet.
2894 * Decryption will be done in SW. */
2895 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
2896 RX_RES_STATUS_BAD_KEY_TTAK)
2897 break;
2898
2899 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
2900 RX_RES_STATUS_BAD_ICV_MIC) {
2901 /* bad ICV, the packet is destroyed since the
2902 * decryption is inplace, drop it */
2903 IWL_DEBUG_RX("Packet destroyed\n");
2904 return -1;
2905 }
2906 case RX_RES_STATUS_SEC_TYPE_WEP:
2907 case RX_RES_STATUS_SEC_TYPE_CCMP:
2908 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
2909 RX_RES_STATUS_DECRYPT_OK) {
2910 IWL_DEBUG_RX("hw decrypt successfully!!!\n");
2911 stats->flag |= RX_FLAG_DECRYPTED;
2912 }
2913 break;
2914
2915 default:
2916 break;
2917 }
2918 return 0;
2919}
2920
2874static u32 iwl4965_translate_rx_status(u32 decrypt_in) 2921static u32 iwl4965_translate_rx_status(u32 decrypt_in)
2875{ 2922{
2876 u32 decrypt_out = 0; 2923 u32 decrypt_out = 0;
@@ -3000,8 +3047,10 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data,
3000 stats->flag = 0; 3047 stats->flag = 0;
3001 hdr = (struct ieee80211_hdr *)rxb->skb->data; 3048 hdr = (struct ieee80211_hdr *)rxb->skb->data;
3002 3049
3003 if (!priv->cfg->mod_params->sw_crypto) 3050 /* in case of HW accelerated crypto and bad decryption, drop */
3004 iwl4965_set_decrypted_flag(priv, rxb->skb, ampdu_status, stats); 3051 if (!priv->cfg->mod_params->sw_crypto &&
3052 iwl4965_set_decrypted_flag(priv, hdr, ampdu_status, stats))
3053 return;
3005 3054
3006 if (priv->add_radiotap) 3055 if (priv->add_radiotap)
3007 iwl4965_add_radiotap(priv, rxb->skb, rx_start, stats, ampdu_status); 3056 iwl4965_add_radiotap(priv, rxb->skb, rx_start, stats, ampdu_status);