mac80211: 802.11w - Optional software CCMP for management frames
authorJouni Malinen <j@w1.fi>
Thu, 8 Jan 2009 11:32:10 +0000 (13:32 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 29 Jan 2009 21:00:08 +0000 (16:00 -0500)
If driver/firmware/hardware does not support CCMP for management
frames, it can now request mac80211 to take care of encrypting and
decrypting management frames (when MFP is enabled) in software. The
will need to add this new IEEE80211_KEY_FLAG_SW_MGMT flag when a CCMP
key is being configured for TX side and return the undecrypted frames
on RX side without RX_FLAG_DECRYPTED flag to use software CCMP for
management frames (but hardware for data frames).

Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
include/net/mac80211.h
net/mac80211/wpa.c

index 61f1f37a9e27c248a0c1793358640b55ed28faf9..00a50a38c7f237fa8add4ecb7d4e3dc2b4851943 100644 (file)
@@ -686,12 +686,16 @@ enum ieee80211_key_len {
  *     generation in software.
  * @IEEE80211_KEY_FLAG_PAIRWISE: Set by mac80211, this flag indicates
  *     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
+ *     CCMP key if it requires CCMP encryption of management frames (MFP) to
+ *     be done in software.
  */
 enum ieee80211_key_flags {
        IEEE80211_KEY_FLAG_WMM_STA      = 1<<0,
        IEEE80211_KEY_FLAG_GENERATE_IV  = 1<<1,
        IEEE80211_KEY_FLAG_GENERATE_MMIC= 1<<2,
        IEEE80211_KEY_FLAG_PAIRWISE     = 1<<3,
+       IEEE80211_KEY_FLAG_SW_MGMT      = 1<<4,
 };
 
 /**
index 53e11e6ff66edd5b99475e7653d1e63f25bfa984..9101b48ec2ae69e3a6c0e00e823876f230818e81 100644 (file)
@@ -367,9 +367,14 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
        int hdrlen, len, tail;
        u8 *pos, *pn;
        int i;
+       bool skip_hw;
+
+       skip_hw = (tx->key->conf.flags & IEEE80211_KEY_FLAG_SW_MGMT) &&
+               ieee80211_is_mgmt(hdr->frame_control);
 
        if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
-           !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
+           !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
+           !skip_hw) {
                /* hwaccel - with no need for preallocated room for CCMP
                 * header or MIC fields */
                info->control.hw_key = &tx->key->conf;
@@ -404,7 +409,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
 
        ccmp_pn2hdr(pos, pn, key->conf.keyidx);
 
-       if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
+       if ((key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && !skip_hw) {
                /* hwaccel - with preallocated room for CCMP header */
                info->control.hw_key = &tx->key->conf;
                return 0;