mac80211: Get IV len from key conf and not cipher scheme

When a key is installed using a cipher scheme, set a new
internal key flag (KEY_FLAG_CIPHER_SCHEME) on it, to allow
distinguishing such keys more easily.

In particular, use this flag on the TX path instead of
testing the sta->cipher_scheme pointer, as the station is
NULL for broad-/multicast message, and use the key's iv_len
instead of the cipher scheme information.

Signed-off-by: Cedric Izoard <cedric.izoard@ceva-dsp.com>
[add missing documentation, rewrite commit message]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Cedric Izoard 2015-03-17 10:47:33 +00:00 committed by Johannes Berg
parent 8a4988d137
commit c7ef38e0cc
3 changed files with 9 additions and 7 deletions

View File

@ -492,6 +492,7 @@ ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
for (j = 0; j < len; j++) for (j = 0; j < len; j++)
key->u.gen.rx_pn[i][j] = key->u.gen.rx_pn[i][j] =
seq[len - j - 1]; seq[len - j - 1];
key->flags |= KEY_FLAG_CIPHER_SCHEME;
} }
} }
memcpy(key->conf.key, key_data, key_len); memcpy(key->conf.key, key_data, key_len);

View File

@ -30,10 +30,12 @@ struct sta_info;
* @KEY_FLAG_UPLOADED_TO_HARDWARE: Indicates that this key is present * @KEY_FLAG_UPLOADED_TO_HARDWARE: Indicates that this key is present
* in the hardware for TX crypto hardware acceleration. * in the hardware for TX crypto hardware acceleration.
* @KEY_FLAG_TAINTED: Key is tainted and packets should be dropped. * @KEY_FLAG_TAINTED: Key is tainted and packets should be dropped.
* @KEY_FLAG_CIPHER_SCHEME: This key is for a hardware cipher scheme
*/ */
enum ieee80211_internal_key_flags { enum ieee80211_internal_key_flags {
KEY_FLAG_UPLOADED_TO_HARDWARE = BIT(0), KEY_FLAG_UPLOADED_TO_HARDWARE = BIT(0),
KEY_FLAG_TAINTED = BIT(1), KEY_FLAG_TAINTED = BIT(1),
KEY_FLAG_CIPHER_SCHEME = BIT(2),
}; };
enum ieee80211_internal_tkip_state { enum ieee80211_internal_tkip_state {

View File

@ -780,9 +780,8 @@ ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_key *key = tx->key; struct ieee80211_key *key = tx->key;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
const struct ieee80211_cipher_scheme *cs = key->sta->cipher_scheme;
int hdrlen; int hdrlen;
u8 *pos; u8 *pos, iv_len = key->conf.iv_len;
if (info->control.hw_key && if (info->control.hw_key &&
!(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) { !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
@ -790,14 +789,14 @@ ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx,
return TX_CONTINUE; return TX_CONTINUE;
} }
if (unlikely(skb_headroom(skb) < cs->hdr_len && if (unlikely(skb_headroom(skb) < iv_len &&
pskb_expand_head(skb, cs->hdr_len, 0, GFP_ATOMIC))) pskb_expand_head(skb, iv_len, 0, GFP_ATOMIC)))
return TX_DROP; return TX_DROP;
hdrlen = ieee80211_hdrlen(hdr->frame_control); hdrlen = ieee80211_hdrlen(hdr->frame_control);
pos = skb_push(skb, cs->hdr_len); pos = skb_push(skb, iv_len);
memmove(pos, pos + cs->hdr_len, hdrlen); memmove(pos, pos + iv_len, hdrlen);
return TX_CONTINUE; return TX_CONTINUE;
} }
@ -1217,7 +1216,7 @@ ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx)
if (!info->control.hw_key) if (!info->control.hw_key)
return TX_DROP; return TX_DROP;
if (tx->key->sta->cipher_scheme) { if (tx->key->flags & KEY_FLAG_CIPHER_SCHEME) {
res = ieee80211_crypto_cs_encrypt(tx, skb); res = ieee80211_crypto_cs_encrypt(tx, skb);
if (res != TX_CONTINUE) if (res != TX_CONTINUE)
return res; return res;