aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2015-01-22 12:44:19 -0500
committerJohannes Berg <johannes.berg@intel.com>2015-01-22 16:01:01 -0500
commitfa7e1fbcb52cc9efab394526a566d80fb31529bb (patch)
tree3fe7b35805171a28a7f23389a2a40cee834e5381
parent54330bf63b49683d006d8f3857d45722a8c0fbff (diff)
mac80211: allow drivers to control software crypto
Some drivers unfortunately cannot support software crypto, but mac80211 currently assumes that they do. This has the issue that if the hardware enabling fails for some reason, the software fallback is used, which won't work. This clearly isn't desirable, the error should be reported and the key setting refused. Support this in mac80211 by allowing drivers to set a new HW flag IEEE80211_HW_SW_CRYPTO_CONTROL, in which case mac80211 will only allow software fallback if the set_key() method returns 1. The driver will also need to advertise supported cipher suites so that mac80211 doesn't advertise any (future) software ciphers that the driver can't actually do. While at it, to make it easier to support this, refactor the ieee80211_init_cipher_suites() code. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/mac80211.h12
-rw-r--r--net/mac80211/key.c10
-rw-r--r--net/mac80211/main.c65
3 files changed, 58 insertions, 29 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 275ee56152ad..33b87c50a4cf 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1634,6 +1634,12 @@ struct ieee80211_tx_control {
1634 * be created. It is expected user-space will create vifs as 1634 * be created. It is expected user-space will create vifs as
1635 * desired (and thus have them named as desired). 1635 * desired (and thus have them named as desired).
1636 * 1636 *
1637 * @IEEE80211_HW_SW_CRYPTO_CONTROL: The driver wants to control which of the
1638 * crypto algorithms can be done in software - so don't automatically
1639 * try to fall back to it if hardware crypto fails, but do so only if
1640 * the driver returns 1. This also forces the driver to advertise its
1641 * supported cipher suites.
1642 *
1637 * @IEEE80211_HW_QUEUE_CONTROL: The driver wants to control per-interface 1643 * @IEEE80211_HW_QUEUE_CONTROL: The driver wants to control per-interface
1638 * queue mapping in order to use different queues (not just one per AC) 1644 * queue mapping in order to use different queues (not just one per AC)
1639 * for different virtual interfaces. See the doc section on HW queue 1645 * for different virtual interfaces. See the doc section on HW queue
@@ -1681,6 +1687,7 @@ enum ieee80211_hw_flags {
1681 IEEE80211_HW_MFP_CAPABLE = 1<<13, 1687 IEEE80211_HW_MFP_CAPABLE = 1<<13,
1682 IEEE80211_HW_WANT_MONITOR_VIF = 1<<14, 1688 IEEE80211_HW_WANT_MONITOR_VIF = 1<<14,
1683 IEEE80211_HW_NO_AUTO_VIF = 1<<15, 1689 IEEE80211_HW_NO_AUTO_VIF = 1<<15,
1690 IEEE80211_HW_SW_CRYPTO_CONTROL = 1<<16,
1684 /* free slots */ 1691 /* free slots */
1685 IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, 1692 IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18,
1686 IEEE80211_HW_CONNECTION_MONITOR = 1<<19, 1693 IEEE80211_HW_CONNECTION_MONITOR = 1<<19,
@@ -1955,6 +1962,11 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
1955 * added; if you return 0 then hw_key_idx must be assigned to the 1962 * added; if you return 0 then hw_key_idx must be assigned to the
1956 * hardware key index, you are free to use the full u8 range. 1963 * hardware key index, you are free to use the full u8 range.
1957 * 1964 *
1965 * Note that in the case that the @IEEE80211_HW_SW_CRYPTO_CONTROL flag is
1966 * set, mac80211 will not automatically fall back to software crypto if
1967 * enabling hardware crypto failed. The set_key() call may also return the
1968 * value 1 to permit this specific key/algorithm to be done in software.
1969 *
1958 * When the cmd is %DISABLE_KEY then it must succeed. 1970 * When the cmd is %DISABLE_KEY then it must succeed.
1959 * 1971 *
1960 * Note that it is permissible to not decrypt a frame even if a key 1972 * Note that it is permissible to not decrypt a frame even if a key
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index f8d9f0ee59bf..5167c53aa15f 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -90,7 +90,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
90{ 90{
91 struct ieee80211_sub_if_data *sdata; 91 struct ieee80211_sub_if_data *sdata;
92 struct sta_info *sta; 92 struct sta_info *sta;
93 int ret; 93 int ret = -EOPNOTSUPP;
94 94
95 might_sleep(); 95 might_sleep();
96 96
@@ -150,7 +150,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
150 return 0; 150 return 0;
151 } 151 }
152 152
153 if (ret != -ENOSPC && ret != -EOPNOTSUPP) 153 if (ret != -ENOSPC && ret != -EOPNOTSUPP && ret != 1)
154 sdata_err(sdata, 154 sdata_err(sdata,
155 "failed to set key (%d, %pM) to hardware (%d)\n", 155 "failed to set key (%d, %pM) to hardware (%d)\n",
156 key->conf.keyidx, 156 key->conf.keyidx,
@@ -163,7 +163,11 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
163 case WLAN_CIPHER_SUITE_TKIP: 163 case WLAN_CIPHER_SUITE_TKIP:
164 case WLAN_CIPHER_SUITE_CCMP: 164 case WLAN_CIPHER_SUITE_CCMP:
165 case WLAN_CIPHER_SUITE_AES_CMAC: 165 case WLAN_CIPHER_SUITE_AES_CMAC:
166 /* all of these we can do in software */ 166 /* all of these we can do in software - if driver can */
167 if (ret == 1)
168 return 0;
169 if (key->local->hw.flags & IEEE80211_HW_SW_CRYPTO_CONTROL)
170 return -EINVAL;
167 return 0; 171 return 0;
168 default: 172 default:
169 return -EINVAL; 173 return -EINVAL;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 46264cb6604b..ea6b82ac4f0b 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -658,7 +658,6 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
658 bool have_wep = !(IS_ERR(local->wep_tx_tfm) || 658 bool have_wep = !(IS_ERR(local->wep_tx_tfm) ||
659 IS_ERR(local->wep_rx_tfm)); 659 IS_ERR(local->wep_rx_tfm));
660 bool have_mfp = local->hw.flags & IEEE80211_HW_MFP_CAPABLE; 660 bool have_mfp = local->hw.flags & IEEE80211_HW_MFP_CAPABLE;
661 const struct ieee80211_cipher_scheme *cs = local->hw.cipher_schemes;
662 int n_suites = 0, r = 0, w = 0; 661 int n_suites = 0, r = 0, w = 0;
663 u32 *suites; 662 u32 *suites;
664 static const u32 cipher_suites[] = { 663 static const u32 cipher_suites[] = {
@@ -672,12 +671,38 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
672 WLAN_CIPHER_SUITE_AES_CMAC 671 WLAN_CIPHER_SUITE_AES_CMAC
673 }; 672 };
674 673
675 /* Driver specifies the ciphers, we have nothing to do... */ 674 if (local->hw.flags & IEEE80211_HW_SW_CRYPTO_CONTROL ||
676 if (local->hw.wiphy->cipher_suites && have_wep) 675 local->hw.wiphy->cipher_suites) {
677 return 0; 676 /* If the driver advertises, or doesn't support SW crypto,
677 * we only need to remove WEP if necessary.
678 */
679 if (have_wep)
680 return 0;
681
682 /* well if it has _no_ ciphers ... fine */
683 if (!local->hw.wiphy->n_cipher_suites)
684 return 0;
685
686 /* Driver provides cipher suites, but we need to exclude WEP */
687 suites = kmemdup(local->hw.wiphy->cipher_suites,
688 sizeof(u32) * local->hw.wiphy->n_cipher_suites,
689 GFP_KERNEL);
690 if (!suites)
691 return -ENOMEM;
678 692
679 /* Set up cipher suites if driver relies on mac80211 cipher defs */ 693 for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) {
680 if (!local->hw.wiphy->cipher_suites && !cs) { 694 u32 suite = local->hw.wiphy->cipher_suites[r];
695
696 if (suite == WLAN_CIPHER_SUITE_WEP40 ||
697 suite == WLAN_CIPHER_SUITE_WEP104)
698 continue;
699 suites[w++] = suite;
700 }
701 } else if (!local->hw.cipher_schemes) {
702 /* If the driver doesn't have cipher schemes, there's nothing
703 * else to do other than assign the (software supported and
704 * perhaps offloaded) cipher suites.
705 */
681 local->hw.wiphy->cipher_suites = cipher_suites; 706 local->hw.wiphy->cipher_suites = cipher_suites;
682 local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 707 local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
683 708
@@ -689,12 +714,16 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
689 local->hw.wiphy->n_cipher_suites -= 2; 714 local->hw.wiphy->n_cipher_suites -= 2;
690 } 715 }
691 716
717 /* not dynamically allocated, so just return */
692 return 0; 718 return 0;
693 } 719 } else {
720 const struct ieee80211_cipher_scheme *cs;
694 721
695 if (!local->hw.wiphy->cipher_suites) { 722 cs = local->hw.cipher_schemes;
696 /* 723
697 * Driver specifies cipher schemes only 724 /* Driver specifies cipher schemes only (but not cipher suites
725 * including the schemes)
726 *
698 * We start counting ciphers defined by schemes, TKIP and CCMP 727 * We start counting ciphers defined by schemes, TKIP and CCMP
699 */ 728 */
700 n_suites = local->hw.n_cipher_schemes + 2; 729 n_suites = local->hw.n_cipher_schemes + 2;
@@ -724,22 +753,6 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
724 753
725 for (r = 0; r < local->hw.n_cipher_schemes; r++) 754 for (r = 0; r < local->hw.n_cipher_schemes; r++)
726 suites[w++] = cs[r].cipher; 755 suites[w++] = cs[r].cipher;
727 } else {
728 /* Driver provides cipher suites, but we need to exclude WEP */
729 suites = kmemdup(local->hw.wiphy->cipher_suites,
730 sizeof(u32) * local->hw.wiphy->n_cipher_suites,
731 GFP_KERNEL);
732 if (!suites)
733 return -ENOMEM;
734
735 for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) {
736 u32 suite = local->hw.wiphy->cipher_suites[r];
737
738 if (suite == WLAN_CIPHER_SUITE_WEP40 ||
739 suite == WLAN_CIPHER_SUITE_WEP104)
740 continue;
741 suites[w++] = suite;
742 }
743 } 756 }
744 757
745 local->hw.wiphy->cipher_suites = suites; 758 local->hw.wiphy->cipher_suites = suites;