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>
This commit is contained in:
Родитель
3b7b72eed1
Коммит
077a915489
|
@ -901,6 +901,10 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
|
||||||
* @IEEE80211_KEY_FLAG_SW_MGMT: This flag should be set by the driver for a
|
* @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
|
* 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
|
||||||
|
* for a CCMP key if space should be prepared for the IV, but the IV
|
||||||
|
* itself should not be generated. Do not set together with
|
||||||
|
* @IEEE80211_KEY_FLAG_GENERATE_IV on the same key.
|
||||||
*/
|
*/
|
||||||
enum ieee80211_key_flags {
|
enum ieee80211_key_flags {
|
||||||
IEEE80211_KEY_FLAG_WMM_STA = 1<<0,
|
IEEE80211_KEY_FLAG_WMM_STA = 1<<0,
|
||||||
|
@ -908,6 +912,7 @@ enum ieee80211_key_flags {
|
||||||
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 = 1<<4,
|
||||||
|
IEEE80211_KEY_FLAG_PUT_IV_SPACE = 1<<5,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -133,9 +133,13 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
|
||||||
key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
|
key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
|
||||||
|
|
||||||
if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
|
if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
|
||||||
(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
|
(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
|
||||||
|
(key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
|
||||||
sdata->crypto_tx_tailroom_needed_cnt--;
|
sdata->crypto_tx_tailroom_needed_cnt--;
|
||||||
|
|
||||||
|
WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
|
||||||
|
(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +182,8 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
|
||||||
sdata = key->sdata;
|
sdata = key->sdata;
|
||||||
|
|
||||||
if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
|
if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
|
||||||
(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
|
(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
|
||||||
|
(key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
|
||||||
increment_tailroom_need_count(sdata);
|
increment_tailroom_need_count(sdata);
|
||||||
|
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
||||||
|
|
|
@ -390,7 +390,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
|
||||||
u8 scratch[6 * AES_BLOCK_SIZE];
|
u8 scratch[6 * AES_BLOCK_SIZE];
|
||||||
|
|
||||||
if (info->control.hw_key &&
|
if (info->control.hw_key &&
|
||||||
!(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
|
!(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
|
||||||
|
!(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
|
||||||
/*
|
/*
|
||||||
* hwaccel has no need for preallocated room for CCMP
|
* hwaccel has no need for preallocated room for CCMP
|
||||||
* header or MIC fields
|
* header or MIC fields
|
||||||
|
@ -412,6 +413,11 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
|
||||||
|
|
||||||
pos = skb_push(skb, CCMP_HDR_LEN);
|
pos = skb_push(skb, CCMP_HDR_LEN);
|
||||||
memmove(pos, pos + CCMP_HDR_LEN, hdrlen);
|
memmove(pos, pos + CCMP_HDR_LEN, hdrlen);
|
||||||
|
|
||||||
|
/* the HW only needs room for the IV, but not the actual IV */
|
||||||
|
if (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
hdr = (struct ieee80211_hdr *) pos;
|
hdr = (struct ieee80211_hdr *) pos;
|
||||||
pos += hdrlen;
|
pos += hdrlen;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче