aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2011-10-23 02:21:41 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-11-08 15:54:27 -0500
commit077a9154898b374f20555adc3f620cccd02581d6 (patch)
tree77549521a0633899874a2b7f694f240cd7e61414
parent3b7b72eed19684824806b3fbefef653a180ef2b0 (diff)
mac80211: support adding IV-room in the skb for CCMP keys
Some cards can generate CCMP IVs in HW, but require the space for the IV to be pre-allocated in the frame at the correct offset. Add a key flag that allows us to achieve this. Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--include/net/mac80211.h5
-rw-r--r--net/mac80211/key.c9
-rw-r--r--net/mac80211/wpa.c8
3 files changed, 19 insertions, 3 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index dc1123aa8181..f4e0ab49db20 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -901,6 +901,10 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
901 * @IEEE80211_KEY_FLAG_SW_MGMT: This flag should be set by the driver for a 901 * @IEEE80211_KEY_FLAG_SW_MGMT: This flag should be set by the driver for a
902 * CCMP key if it requires CCMP encryption of management frames (MFP) to 902 * CCMP key if it requires CCMP encryption of management frames (MFP) to
903 * be done in software. 903 * be done in software.
904 * @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver
905 * for a CCMP key if space should be prepared for the IV, but the IV
906 * itself should not be generated. Do not set together with
907 * @IEEE80211_KEY_FLAG_GENERATE_IV on the same key.
904 */ 908 */
905enum ieee80211_key_flags { 909enum ieee80211_key_flags {
906 IEEE80211_KEY_FLAG_WMM_STA = 1<<0, 910 IEEE80211_KEY_FLAG_WMM_STA = 1<<0,
@@ -908,6 +912,7 @@ enum ieee80211_key_flags {
908 IEEE80211_KEY_FLAG_GENERATE_MMIC= 1<<2, 912 IEEE80211_KEY_FLAG_GENERATE_MMIC= 1<<2,
909 IEEE80211_KEY_FLAG_PAIRWISE = 1<<3, 913 IEEE80211_KEY_FLAG_PAIRWISE = 1<<3,
910 IEEE80211_KEY_FLAG_SW_MGMT = 1<<4, 914 IEEE80211_KEY_FLAG_SW_MGMT = 1<<4,
915 IEEE80211_KEY_FLAG_PUT_IV_SPACE = 1<<5,
911}; 916};
912 917
913/** 918/**
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 756b157c2edd..17a5220ed450 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -133,9 +133,13 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
133 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; 133 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
134 134
135 if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || 135 if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
136 (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))) 136 (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
137 (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
137 sdata->crypto_tx_tailroom_needed_cnt--; 138 sdata->crypto_tx_tailroom_needed_cnt--;
138 139
140 WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
141 (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV));
142
139 return 0; 143 return 0;
140 } 144 }
141 145
@@ -178,7 +182,8 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
178 sdata = key->sdata; 182 sdata = key->sdata;
179 183
180 if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || 184 if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
181 (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))) 185 (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
186 (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
182 increment_tailroom_need_count(sdata); 187 increment_tailroom_need_count(sdata);
183 188
184 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 189 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index f614ce7bb6e3..13efab5bf12a 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -390,7 +390,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
390 u8 scratch[6 * AES_BLOCK_SIZE]; 390 u8 scratch[6 * AES_BLOCK_SIZE];
391 391
392 if (info->control.hw_key && 392 if (info->control.hw_key &&
393 !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { 393 !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
394 !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
394 /* 395 /*
395 * hwaccel has no need for preallocated room for CCMP 396 * hwaccel has no need for preallocated room for CCMP
396 * header or MIC fields 397 * header or MIC fields
@@ -412,6 +413,11 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
412 413
413 pos = skb_push(skb, CCMP_HDR_LEN); 414 pos = skb_push(skb, CCMP_HDR_LEN);
414 memmove(pos, pos + CCMP_HDR_LEN, hdrlen); 415 memmove(pos, pos + CCMP_HDR_LEN, hdrlen);
416
417 /* the HW only needs room for the IV, but not the actual IV */
418 if (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)
419 return 0;
420
415 hdr = (struct ieee80211_hdr *) pos; 421 hdr = (struct ieee80211_hdr *) pos;
416 pos += hdrlen; 422 pos += hdrlen;
417 423