Commit e548c49e authored by Johannes Berg's avatar Johannes Berg

mac80211: add key flag for management keys

Mark keys that might be used to receive management
frames so drivers can fall back on software crypto
for them if they don't support hardware offload.
As the new flag is only set correctly for RX keys
and the existing IEEE80211_KEY_FLAG_SW_MGMT flag
can only affect TX, also rename the latter to
IEEE80211_KEY_FLAG_SW_MGMT_TX.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 2cc59e78
...@@ -524,7 +524,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ...@@ -524,7 +524,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (key->cipher == WLAN_CIPHER_SUITE_TKIP) if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
if (key->cipher == WLAN_CIPHER_SUITE_CCMP) if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
ret = 0; ret = 0;
} }
break; break;
......
...@@ -1449,7 +1449,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, ...@@ -1449,7 +1449,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw,
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
if (priv->ah->sw_mgmt_crypto && if (priv->ah->sw_mgmt_crypto &&
key->cipher == WLAN_CIPHER_SUITE_CCMP) key->cipher == WLAN_CIPHER_SUITE_CCMP)
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
ret = 0; ret = 0;
} }
break; break;
......
...@@ -1441,7 +1441,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, ...@@ -1441,7 +1441,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
if (sc->sc_ah->sw_mgmt_crypto && if (sc->sc_ah->sw_mgmt_crypto &&
key->cipher == WLAN_CIPHER_SUITE_CCMP) key->cipher == WLAN_CIPHER_SUITE_CCMP)
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
ret = 0; ret = 0;
} }
break; break;
......
...@@ -973,21 +973,29 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif) ...@@ -973,21 +973,29 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
* generation in software. * generation in software.
* @IEEE80211_KEY_FLAG_PAIRWISE: Set by mac80211, this flag indicates * @IEEE80211_KEY_FLAG_PAIRWISE: Set by mac80211, this flag indicates
* that the key is pairwise rather then a shared key. * that the key is pairwise rather then a shared key.
* @IEEE80211_KEY_FLAG_SW_MGMT: This flag should be set by the driver for a * @IEEE80211_KEY_FLAG_SW_MGMT_TX: This flag should be set by the driver for a
* CCMP key if it requires CCMP encryption of management frames (MFP) to * CCMP key if it requires CCMP encryption of management frames (MFP) to
* be done in software. * be done in software.
* @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver * @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver
* if space should be prepared for the IV, but the IV * if space should be prepared for the IV, but the IV
* itself should not be generated. Do not set together with * itself should not be generated. Do not set together with
* @IEEE80211_KEY_FLAG_GENERATE_IV on the same key. * @IEEE80211_KEY_FLAG_GENERATE_IV on the same key.
* @IEEE80211_KEY_FLAG_RX_MGMT: This key will be used to decrypt received
* management frames. The flag can help drivers that have a hardware
* crypto implementation that doesn't deal with management frames
* properly by allowing them to not upload the keys to hardware and
* fall back to software crypto. Note that this flag deals only with
* RX, if your crypto engine can't deal with TX you can also set the
* %IEEE80211_KEY_FLAG_SW_MGMT_TX flag to encrypt such frames in SW.
*/ */
enum ieee80211_key_flags { enum ieee80211_key_flags {
IEEE80211_KEY_FLAG_WMM_STA = 1<<0, IEEE80211_KEY_FLAG_WMM_STA = 1<<0,
IEEE80211_KEY_FLAG_GENERATE_IV = 1<<1, IEEE80211_KEY_FLAG_GENERATE_IV = 1<<1,
IEEE80211_KEY_FLAG_GENERATE_MMIC= 1<<2, IEEE80211_KEY_FLAG_GENERATE_MMIC= 1<<2,
IEEE80211_KEY_FLAG_PAIRWISE = 1<<3, IEEE80211_KEY_FLAG_PAIRWISE = 1<<3,
IEEE80211_KEY_FLAG_SW_MGMT = 1<<4, IEEE80211_KEY_FLAG_SW_MGMT_TX = 1<<4,
IEEE80211_KEY_FLAG_PUT_IV_SPACE = 1<<5, IEEE80211_KEY_FLAG_PUT_IV_SPACE = 1<<5,
IEEE80211_KEY_FLAG_RX_MGMT = 1<<6,
}; };
/** /**
......
...@@ -170,6 +170,38 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, ...@@ -170,6 +170,38 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
} }
} }
switch (sdata->vif.type) {
case NL80211_IFTYPE_STATION:
if (sdata->u.mgd.mfp != IEEE80211_MFP_DISABLED)
key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT;
break;
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN:
/* Keys without a station are used for TX only */
if (key->sta && test_sta_flag(key->sta, WLAN_STA_MFP))
key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT;
break;
case NL80211_IFTYPE_ADHOC:
/* no MFP (yet) */
break;
case NL80211_IFTYPE_MESH_POINT:
#ifdef CONFIG_MAC80211_MESH
if (sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)
key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT;
break;
#endif
case NL80211_IFTYPE_WDS:
case NL80211_IFTYPE_MONITOR:
case NL80211_IFTYPE_P2P_DEVICE:
case NL80211_IFTYPE_UNSPECIFIED:
case NUM_NL80211_IFTYPES:
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_P2P_GO:
/* shouldn't happen */
WARN_ON_ONCE(1);
break;
}
err = ieee80211_key_link(key, sdata, sta); err = ieee80211_key_link(key, sdata, sta);
if (err) if (err)
ieee80211_key_free(sdata->local, key); ieee80211_key_free(sdata->local, key);
......
...@@ -580,7 +580,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) ...@@ -580,7 +580,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
tx->key = NULL; tx->key = NULL;
else else
skip_hw = (tx->key->conf.flags & skip_hw = (tx->key->conf.flags &
IEEE80211_KEY_FLAG_SW_MGMT) && IEEE80211_KEY_FLAG_SW_MGMT_TX) &&
ieee80211_is_mgmt(hdr->frame_control); ieee80211_is_mgmt(hdr->frame_control);
break; break;
case WLAN_CIPHER_SUITE_AES_CMAC: case WLAN_CIPHER_SUITE_AES_CMAC:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment