|
@@ -92,6 +92,7 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
|
|
|
int keylen, int keyidx)
|
|
|
{
|
|
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
|
|
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
|
|
unsigned int hdrlen;
|
|
|
u8 *newhdr;
|
|
|
|
|
@@ -104,6 +105,12 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
|
|
|
hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
|
|
newhdr = skb_push(skb, WEP_IV_LEN);
|
|
|
memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen);
|
|
|
+
|
|
|
+ /* the HW only needs room for the IV, but not the actual IV */
|
|
|
+ if (info->control.hw_key &&
|
|
|
+ (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
|
|
|
+ return newhdr + hdrlen;
|
|
|
+
|
|
|
ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen);
|
|
|
return newhdr + hdrlen;
|
|
|
}
|
|
@@ -313,14 +320,15 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
|
|
|
static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
|
|
|
{
|
|
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
|
|
+ struct ieee80211_key_conf *hw_key = info->control.hw_key;
|
|
|
|
|
|
- if (!info->control.hw_key) {
|
|
|
+ if (!hw_key) {
|
|
|
if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key,
|
|
|
tx->key->conf.keylen,
|
|
|
tx->key->conf.keyidx))
|
|
|
return -1;
|
|
|
- } else if (info->control.hw_key->flags &
|
|
|
- IEEE80211_KEY_FLAG_GENERATE_IV) {
|
|
|
+ } else if ((hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
|
|
|
+ (hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
|
|
|
if (!ieee80211_wep_add_iv(tx->local, skb,
|
|
|
tx->key->conf.keylen,
|
|
|
tx->key->conf.keyidx))
|