diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2008-05-15 01:54:09 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-21 21:48:01 -0400 |
commit | ccc038abe4cb00cf56aeae5b1df47fcc4ed4136c (patch) | |
tree | 0c35fec8a1c9e7179f9b756d30c3f8af02d9bfa5 /drivers/net/wireless/iwlwifi/iwl-sta.c | |
parent | a98410139a2ef6553ae5d73bf12bb9a68d0b38b9 (diff) |
iwlwifi: clean up and bug fix for security
This patch cleans up code in security.
1) uses the new pointer to ieee80211_key_conf passed with the tx_control.
2) resolves bug reported by Mirco Tischler (sends ADD_STA in ASYNC mode)
3) resolves bug reported by Volker Braun regarding dynamic WEP
4) drops a WEP packet which has been garbaged by firmware. This can
happen upon rekeying.
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-sta.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-sta.c | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index c8e468fb3caa..99ee1e14e29e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -324,7 +324,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, | |||
324 | unsigned long flags; | 324 | unsigned long flags; |
325 | 325 | ||
326 | keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; | 326 | keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; |
327 | keyconf->hw_key_idx = keyconf->keyidx; | 327 | keyconf->hw_key_idx = HW_KEY_DEFAULT; |
328 | priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP; | 328 | priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP; |
329 | 329 | ||
330 | spin_lock_irqsave(&priv->sta_lock, flags); | 330 | spin_lock_irqsave(&priv->sta_lock, flags); |
@@ -354,7 +354,6 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, | |||
354 | int ret; | 354 | int ret; |
355 | 355 | ||
356 | keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; | 356 | keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; |
357 | keyconf->hw_key_idx = keyconf->keyidx; | ||
358 | 357 | ||
359 | key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK); | 358 | key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK); |
360 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); | 359 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); |
@@ -411,7 +410,6 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, | |||
411 | key_flags |= STA_KEY_MULTICAST_MSK; | 410 | key_flags |= STA_KEY_MULTICAST_MSK; |
412 | 411 | ||
413 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | 412 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; |
414 | keyconf->hw_key_idx = keyconf->keyidx; | ||
415 | 413 | ||
416 | spin_lock_irqsave(&priv->sta_lock, flags); | 414 | spin_lock_irqsave(&priv->sta_lock, flags); |
417 | priv->stations[sta_id].keyinfo.alg = keyconf->alg; | 415 | priv->stations[sta_id].keyinfo.alg = keyconf->alg; |
@@ -449,12 +447,10 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, | |||
449 | 447 | ||
450 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | 448 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; |
451 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | 449 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; |
452 | keyconf->hw_key_idx = keyconf->keyidx; | ||
453 | 450 | ||
454 | spin_lock_irqsave(&priv->sta_lock, flags); | 451 | spin_lock_irqsave(&priv->sta_lock, flags); |
455 | 452 | ||
456 | priv->stations[sta_id].keyinfo.alg = keyconf->alg; | 453 | priv->stations[sta_id].keyinfo.alg = keyconf->alg; |
457 | priv->stations[sta_id].keyinfo.conf = keyconf; | ||
458 | priv->stations[sta_id].keyinfo.keylen = 16; | 454 | priv->stations[sta_id].keyinfo.keylen = 16; |
459 | 455 | ||
460 | if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) | 456 | if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) |
@@ -483,7 +479,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, | |||
483 | u16 key_flags; | 479 | u16 key_flags; |
484 | u8 keyidx; | 480 | u8 keyidx; |
485 | 481 | ||
486 | priv->key_mapping_key = 0; | 482 | priv->key_mapping_key--; |
487 | 483 | ||
488 | spin_lock_irqsave(&priv->sta_lock, flags); | 484 | spin_lock_irqsave(&priv->sta_lock, flags); |
489 | key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags); | 485 | key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags); |
@@ -514,31 +510,32 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, | |||
514 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 510 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
515 | 511 | ||
516 | IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); | 512 | IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); |
517 | ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0); | 513 | ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
518 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 514 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
519 | return ret; | 515 | return ret; |
520 | } | 516 | } |
521 | EXPORT_SYMBOL(iwl_remove_dynamic_key); | 517 | EXPORT_SYMBOL(iwl_remove_dynamic_key); |
522 | 518 | ||
523 | int iwl_set_dynamic_key(struct iwl_priv *priv, | 519 | int iwl_set_dynamic_key(struct iwl_priv *priv, |
524 | struct ieee80211_key_conf *key, u8 sta_id) | 520 | struct ieee80211_key_conf *keyconf, u8 sta_id) |
525 | { | 521 | { |
526 | int ret; | 522 | int ret; |
527 | 523 | ||
528 | priv->key_mapping_key = 1; | 524 | priv->key_mapping_key++; |
525 | keyconf->hw_key_idx = HW_KEY_DYNAMIC; | ||
529 | 526 | ||
530 | switch (key->alg) { | 527 | switch (keyconf->alg) { |
531 | case ALG_CCMP: | 528 | case ALG_CCMP: |
532 | ret = iwl_set_ccmp_dynamic_key_info(priv, key, sta_id); | 529 | ret = iwl_set_ccmp_dynamic_key_info(priv, keyconf, sta_id); |
533 | break; | 530 | break; |
534 | case ALG_TKIP: | 531 | case ALG_TKIP: |
535 | ret = iwl_set_tkip_dynamic_key_info(priv, key, sta_id); | 532 | ret = iwl_set_tkip_dynamic_key_info(priv, keyconf, sta_id); |
536 | break; | 533 | break; |
537 | case ALG_WEP: | 534 | case ALG_WEP: |
538 | ret = iwl_set_wep_dynamic_key_info(priv, key, sta_id); | 535 | ret = iwl_set_wep_dynamic_key_info(priv, keyconf, sta_id); |
539 | break; | 536 | break; |
540 | default: | 537 | default: |
541 | IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, key->alg); | 538 | IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, keyconf->alg); |
542 | ret = -EINVAL; | 539 | ret = -EINVAL; |
543 | } | 540 | } |
544 | 541 | ||