diff options
author | Arik Nemtsov <arik@wizery.com> | 2011-10-23 02:21:41 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-11-08 15:54:27 -0500 |
commit | 077a9154898b374f20555adc3f620cccd02581d6 (patch) | |
tree | 77549521a0633899874a2b7f694f240cd7e61414 | |
parent | 3b7b72eed19684824806b3fbefef653a180ef2b0 (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.h | 5 | ||||
-rw-r--r-- | net/mac80211/key.c | 9 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 8 |
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 | */ |
905 | enum ieee80211_key_flags { | 909 | enum 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 | ||