summaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/debugfs_key.c49
-rw-r--r--net/mac80211/ieee80211.c5
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/ieee80211_iface.c3
-rw-r--r--net/mac80211/ieee80211_ioctl.c79
-rw-r--r--net/mac80211/ieee80211_key.h20
-rw-r--r--net/mac80211/ieee80211_sta.c2
-rw-r--r--net/mac80211/key.c28
-rw-r--r--net/mac80211/rx.c22
-rw-r--r--net/mac80211/sta_info.c17
-rw-r--r--net/mac80211/tkip.c18
-rw-r--r--net/mac80211/tx.c6
-rw-r--r--net/mac80211/wep.c18
-rw-r--r--net/mac80211/wpa.c61
14 files changed, 150 insertions, 181 deletions
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 077f907271c..246938c32d4 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -14,17 +14,17 @@
#include "debugfs.h"
#include "debugfs_key.h"
-#define KEY_READ(name, buflen, format_string) \
+#define KEY_READ(name, prop, buflen, format_string) \
static ssize_t key_##name##_read(struct file *file, \
char __user *userbuf, \
size_t count, loff_t *ppos) \
{ \
char buf[buflen]; \
struct ieee80211_key *key = file->private_data; \
- int res = scnprintf(buf, buflen, format_string, key->name); \
+ int res = scnprintf(buf, buflen, format_string, key->prop); \
return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
}
-#define KEY_READ_D(name) KEY_READ(name, 20, "%d\n")
+#define KEY_READ_D(name) KEY_READ(name, name, 20, "%d\n")
#define KEY_OPS(name) \
static const struct file_operations key_ ##name## _ops = { \
@@ -36,10 +36,25 @@ static const struct file_operations key_ ##name## _ops = { \
KEY_READ_##format(name) \
KEY_OPS(name)
-KEY_FILE(keylen, D);
-KEY_FILE(force_sw_encrypt, D);
-KEY_FILE(keyidx, D);
-KEY_FILE(hw_key_idx, D);
+#define KEY_CONF_READ(name, buflen, format_string) \
+ KEY_READ(conf_##name, conf.name, buflen, format_string)
+#define KEY_CONF_READ_D(name) KEY_CONF_READ(name, 20, "%d\n")
+#define KEY_CONF_READ_X(name) KEY_CONF_READ(name, 20, "0x%x\n")
+
+#define KEY_CONF_OPS(name) \
+static const struct file_operations key_ ##name## _ops = { \
+ .read = key_conf_##name##_read, \
+ .open = mac80211_open_file_generic, \
+}
+
+#define KEY_CONF_FILE(name, format) \
+ KEY_CONF_READ_##format(name) \
+ KEY_CONF_OPS(name)
+
+KEY_CONF_FILE(keylen, D);
+KEY_CONF_FILE(keyidx, D);
+KEY_CONF_FILE(hw_key_idx, D);
+KEY_CONF_FILE(flags, X);
KEY_FILE(tx_rx_count, D);
static ssize_t key_algorithm_read(struct file *file,
@@ -49,7 +64,7 @@ static ssize_t key_algorithm_read(struct file *file,
char *alg;
struct ieee80211_key *key = file->private_data;
- switch (key->alg) {
+ switch (key->conf.alg) {
case ALG_WEP:
alg = "WEP\n";
break;
@@ -74,7 +89,7 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
int len;
struct ieee80211_key *key = file->private_data;
- switch (key->alg) {
+ switch (key->conf.alg) {
case ALG_WEP:
len = scnprintf(buf, sizeof(buf), "\n");
break;
@@ -103,7 +118,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
int i, len;
const u8 *rpn;
- switch (key->alg) {
+ switch (key->conf.alg) {
case ALG_WEP:
len = scnprintf(buf, sizeof(buf), "\n");
break;
@@ -139,7 +154,7 @@ static ssize_t key_replays_read(struct file *file, char __user *userbuf,
char buf[20];
int len;
- if (key->alg != ALG_CCMP)
+ if (key->conf.alg != ALG_CCMP)
return 0;
len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
return simple_read_from_buffer(userbuf, count, ppos, buf, len);
@@ -150,12 +165,12 @@ static ssize_t key_key_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
struct ieee80211_key *key = file->private_data;
- int i, res, bufsize = 2*key->keylen+2;
+ int i, res, bufsize = 2 * key->conf.keylen + 2;
char *buf = kmalloc(bufsize, GFP_KERNEL);
char *p = buf;
- for (i = 0; i < key->keylen; i++)
- p += scnprintf(p, bufsize+buf-p, "%02x", key->key[i]);
+ for (i = 0; i < key->conf.keylen; i++)
+ p += scnprintf(p, bufsize + buf - p, "%02x", key->conf.key[i]);
p += scnprintf(p, bufsize+buf-p, "\n");
res = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
kfree(buf);
@@ -185,7 +200,7 @@ void ieee80211_debugfs_key_add(struct ieee80211_local *local,
return;
DEBUGFS_ADD(keylen);
- DEBUGFS_ADD(force_sw_encrypt);
+ DEBUGFS_ADD(flags);
DEBUGFS_ADD(keyidx);
DEBUGFS_ADD(hw_key_idx);
DEBUGFS_ADD(tx_rx_count);
@@ -205,7 +220,7 @@ void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
return;
DEBUGFS_DEL(keylen);
- DEBUGFS_DEL(force_sw_encrypt);
+ DEBUGFS_DEL(flags);
DEBUGFS_DEL(keyidx);
DEBUGFS_DEL(hw_key_idx);
DEBUGFS_DEL(tx_rx_count);
@@ -227,7 +242,7 @@ void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
if (!sdata->debugfsdir)
return;
- sprintf(buf, "../keys/%d", sdata->default_key->keyidx);
+ sprintf(buf, "../keys/%d", sdata->default_key->conf.keyidx);
sdata->debugfs.default_key =
debugfs_create_symlink("default_key", sdata->debugfsdir, buf);
}
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 50d7af3018e..5d5034f36fd 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -890,7 +890,7 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
if (!key)
goto no_key;
- switch (key->alg) {
+ switch (key->conf.alg) {
case ALG_WEP:
iv_len = WEP_IV_LEN;
mic_len = WEP_ICV_LEN;
@@ -907,7 +907,8 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
goto no_key;
}
- if (skb->len >= mic_len && key->force_sw_encrypt)
+ if (skb->len >= mic_len &&
+ (key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT))
skb_trim(skb, skb->len - mic_len);
if (skb->len >= iv_len && skb->len > hdrlen) {
memmove(skb->data + iv_len, skb->data, hdrlen);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ef633a041da..cc87e9d988f 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -816,9 +816,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
int ieee80211_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev);
/* key handling */
-struct ieee80211_key_conf *
-ieee80211_key_data2conf(struct ieee80211_local *local,
- const struct ieee80211_key *data);
struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata,
int idx, size_t key_len, gfp_t flags);
void ieee80211_key_free(struct ieee80211_key *key);
diff --git a/net/mac80211/ieee80211_iface.c b/net/mac80211/ieee80211_iface.c
index 61009176d51..3e59afa23e4 100644
--- a/net/mac80211/ieee80211_iface.c
+++ b/net/mac80211/ieee80211_iface.c
@@ -227,7 +227,8 @@ void ieee80211_if_reinit(struct net_device *dev)
memset(addr, 0xff, ETH_ALEN);
if (local->ops->set_key)
local->ops->set_key(local_to_hw(local), DISABLE_KEY, addr,
- local->keys[i], 0);
+ local->keys[i],
+ local->default_wep_only);
#endif
ieee80211_key_free(sdata->keys[i]);
sdata->keys[i] = NULL;
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index 9964f057bce..380670c7a0c 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -31,29 +31,20 @@ static void ieee80211_set_hw_encryption(struct net_device *dev,
struct sta_info *sta, u8 addr[ETH_ALEN],
struct ieee80211_key *key)
{
- struct ieee80211_key_conf *keyconf = NULL;
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
/* default to sw encryption; this will be cleared by low-level
* driver if the hw supports requested encryption */
if (key)
- key->force_sw_encrypt = 1;
+ key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
- if (key && local->ops->set_key &&
- (keyconf = ieee80211_key_data2conf(local, key))) {
+ if (key && local->ops->set_key) {
if (local->ops->set_key(local_to_hw(local), SET_KEY, addr,
- keyconf, sta ? sta->aid : 0)) {
- key->force_sw_encrypt = 1;
- key->hw_key_idx = HW_KEY_IDX_INVALID;
- } else {
- key->force_sw_encrypt =
- !!(keyconf->flags & IEEE80211_KEY_FORCE_SW_ENCRYPT);
- key->hw_key_idx =
- keyconf->hw_key_idx;
-
+ &key->conf, local->default_wep_only)) {
+ key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
+ key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
}
}
- kfree(keyconf);
}
@@ -66,7 +57,6 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
struct sta_info *sta;
struct ieee80211_key *key, *old_key;
int try_hwaccel = 1;
- struct ieee80211_key_conf *keyconf;
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -154,18 +144,16 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
}
if (alg == ALG_NONE) {
- keyconf = NULL;
if (try_hwaccel && key &&
- key->hw_key_idx != HW_KEY_IDX_INVALID &&
+ key->conf.hw_key_idx != HW_KEY_IDX_INVALID &&
local->ops->set_key &&
- (keyconf = ieee80211_key_data2conf(local, key)) != NULL &&
local->ops->set_key(local_to_hw(local), DISABLE_KEY,
- sta_addr, keyconf, sta ? sta->aid : 0)) {
+ sta_addr, &key->conf,
+ local->default_wep_only)) {
printk(KERN_DEBUG "%s: set_encrypt - low-level disable"
" failed\n", dev->name);
ret = -EINVAL;
}
- kfree(keyconf);
if (set_tx_key || sdata->default_key == key) {
ieee80211_debugfs_key_remove_default(sdata);
@@ -189,22 +177,20 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
/* default to sw encryption; low-level driver sets these if the
* requested encryption is supported */
- key->hw_key_idx = HW_KEY_IDX_INVALID;
- key->force_sw_encrypt = 1;
+ key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
+ key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
- key->alg = alg;
- key->keyidx = idx;
- key->keylen = key_len;
- memcpy(key->key, _key, key_len);
- if (set_tx_key)
- key->default_tx_key = 1;
+ key->conf.alg = alg;
+ key->conf.keyidx = idx;
+ key->conf.keylen = key_len;
+ memcpy(key->conf.key, _key, key_len);
if (alg == ALG_CCMP) {
/* Initialize AES key state here as an optimization
* so that it does not need to be initialized for every
* packet. */
key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(
- key->key);
+ key->conf.key);
if (!key->u.ccmp.tfm) {
ret = -ENOMEM;
goto err_free;
@@ -941,43 +927,38 @@ static int ieee80211_ioctl_giwretry(struct net_device *dev,
static void ieee80211_key_enable_hwaccel(struct ieee80211_local *local,
struct ieee80211_key *key)
{
- struct ieee80211_key_conf *keyconf;
u8 addr[ETH_ALEN];
- if (!key || key->alg != ALG_WEP || !key->force_sw_encrypt ||
+ if (!key || key->conf.alg != ALG_WEP ||
+ !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) ||
(local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP))
return;
memset(addr, 0xff, ETH_ALEN);
- keyconf = ieee80211_key_data2conf(local, key);
- if (keyconf && local->ops->set_key &&
+
+ if (local->ops->set_key)
local->ops->set_key(local_to_hw(local),
- SET_KEY, addr, keyconf, 0) == 0) {
- key->force_sw_encrypt =
- !!(keyconf->flags & IEEE80211_KEY_FORCE_SW_ENCRYPT);
- key->hw_key_idx = keyconf->hw_key_idx;
- }
- kfree(keyconf);
+ SET_KEY, addr, &key->conf,
+ local->default_wep_only);
}
static void ieee80211_key_disable_hwaccel(struct ieee80211_local *local,
struct ieee80211_key *key)
{
- struct ieee80211_key_conf *keyconf;
u8 addr[ETH_ALEN];
- if (!key || key->alg != ALG_WEP || key->force_sw_encrypt ||
+ if (!key || key->conf.alg != ALG_WEP ||
+ (key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) ||
(local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP))
return;
memset(addr, 0xff, ETH_ALEN);
- keyconf = ieee80211_key_data2conf(local, key);
- if (keyconf && local->ops->set_key)
+ if (local->ops->set_key)
local->ops->set_key(local_to_hw(local), DISABLE_KEY,
- addr, keyconf, 0);
- kfree(keyconf);
- key->force_sw_encrypt = 1;
+ addr, &key->conf,
+ local->default_wep_only);
+ key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
}
@@ -1341,9 +1322,9 @@ static int ieee80211_ioctl_giwencode(struct net_device *dev,
return 0;
}
- memcpy(key, sdata->keys[idx]->key,
- min((int)erq->length, sdata->keys[idx]->keylen));
- erq->length = sdata->keys[idx]->keylen;
+ memcpy(key, sdata->keys[idx]->conf.key,
+ min((int)erq->length, sdata->keys[idx]->conf.keylen));
+ erq->length = sdata->keys[idx]->conf.keylen;
erq->flags |= IW_ENCODE_ENABLED;
return 0;
diff --git a/net/mac80211/ieee80211_key.h b/net/mac80211/ieee80211_key.h
index c3338491278..1b5e539c678 100644
--- a/net/mac80211/ieee80211_key.h
+++ b/net/mac80211/ieee80211_key.h
@@ -44,8 +44,6 @@
struct ieee80211_key {
struct kref kref;
- int hw_key_idx; /* filled and used by low-level driver */
- ieee80211_key_alg alg;
union {
struct {
/* last used TSC */
@@ -73,22 +71,16 @@ struct ieee80211_key {
u8 rx_crypto_buf[6 * AES_BLOCK_LEN];
} ccmp;
} u;
- int tx_rx_count; /* number of times this key has been used */
- int keylen;
- /* if the low level driver can provide hardware acceleration it should
- * clear this flag */
- unsigned int force_sw_encrypt:1;
- unsigned int default_tx_key:1; /* This key is the new default TX key
- * (used only for broadcast keys). */
- s8 keyidx; /* WEP key index */
+ /* number of times this key has been used */
+ int tx_rx_count;
#ifdef CONFIG_MAC80211_DEBUGFS
struct {
struct dentry *stalink;
struct dentry *dir;
struct dentry *keylen;
- struct dentry *force_sw_encrypt;
+ struct dentry *flags;
struct dentry *keyidx;
struct dentry *hw_key_idx;
struct dentry *tx_rx_count;
@@ -100,7 +92,11 @@ struct ieee80211_key {
} debugfs;
#endif
- u8 key[0];
+ /*
+ * key config, must be last because it contains key
+ * material as variable length member
+ */
+ struct ieee80211_key_conf conf;
};
#endif /* IEEE80211_KEY_H */
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index fe94ebfcb15..a2443271629 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -904,7 +904,7 @@ static int ieee80211_sta_wep_configured(struct net_device *dev)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (!sdata || !sdata->default_key ||
- sdata->default_key->alg != ALG_WEP)
+ sdata->default_key->conf.alg != ALG_WEP)
return 0;
return 1;
}
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index b67558c2463..92d994f090b 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -13,32 +13,6 @@
#include "debugfs_key.h"
#include "aes_ccm.h"
-struct ieee80211_key_conf *
-ieee80211_key_data2conf(struct ieee80211_local *local,
- const struct ieee80211_key *data)
-{
- struct ieee80211_key_conf *conf;
-
- conf = kmalloc(sizeof(*conf) + data->keylen, GFP_ATOMIC);
- if (!conf)
- return NULL;
-
- conf->hw_key_idx = data->hw_key_idx;
- conf->alg = data->alg;
- conf->keylen = data->keylen;
- conf->flags = 0;
- if (data->force_sw_encrypt)
- conf->flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
- conf->keyidx = data->keyidx;
- if (data->default_tx_key)
- conf->flags |= IEEE80211_KEY_DEFAULT_TX_KEY;
- if (local->default_wep_only)
- conf->flags |= IEEE80211_KEY_DEFAULT_WEP_ONLY;
- memcpy(conf->key, data->key, data->keylen);
-
- return conf;
-}
-
struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata,
int idx, size_t key_len, gfp_t flags)
{
@@ -56,7 +30,7 @@ static void ieee80211_key_release(struct kref *kref)
struct ieee80211_key *key;
key = container_of(kref, struct ieee80211_key, kref);
- if (key->alg == ALG_CCMP)
+ if (key->conf.alg == ALG_CCMP)
ieee80211_aes_key_free(key->u.ccmp.tfm);
ieee80211_debugfs_key_remove(key);
kfree(key);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b52e3305a8f..976b646a40d 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -374,7 +374,7 @@ ieee80211_rx_h_load_key(struct ieee80211_txrx_data *rx)
* pairwise or station-to-station keys, but for WEP we allow
* using a key index as well.
*/
- if (rx->key && rx->key->alg != ALG_WEP &&
+ if (rx->key && rx->key->conf.alg != ALG_WEP &&
!is_multicast_ether_addr(hdr->addr1))
rx->key = NULL;
}
@@ -522,18 +522,15 @@ ieee80211_rx_h_wep_weak_iv_detection(struct ieee80211_txrx_data *rx)
{
if (!rx->sta || !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
(rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
- !rx->key || rx->key->alg != ALG_WEP ||
+ !rx->key || rx->key->conf.alg != ALG_WEP ||
!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
return TXRX_CONTINUE;
/* Check for weak IVs, if hwaccel did not remove IV from the frame */
if ((rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) ||
- rx->key->force_sw_encrypt) {
- u8 *iv = ieee80211_wep_is_weak_iv(rx->skb, rx->key);
- if (iv) {
+ (rx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT))
+ if (ieee80211_wep_is_weak_iv(rx->skb, rx->key))
rx->sta->wep_weak_iv_count++;
- }
- }
return TXRX_CONTINUE;
}
@@ -541,7 +538,7 @@ ieee80211_rx_h_wep_weak_iv_detection(struct ieee80211_txrx_data *rx)
static ieee80211_txrx_result
ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx)
{
- if ((rx->key && rx->key->alg != ALG_WEP) ||
+ if ((rx->key && rx->key->conf.alg != ALG_WEP) ||
!(rx->fc & IEEE80211_FCTL_PROTECTED) ||
((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
@@ -556,7 +553,7 @@ ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx)
}
if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED) ||
- rx->key->force_sw_encrypt) {
+ (rx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
if (net_ratelimit())
printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
@@ -680,7 +677,7 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx)
/* This is the first fragment of a new frame. */
entry = ieee80211_reassemble_add(rx->sdata, frag, seq,
rx->u.rx.queue, &(rx->skb));
- if (rx->key && rx->key->alg == ALG_CCMP &&
+ if (rx->key && rx->key->conf.alg == ALG_CCMP &&
(rx->fc & IEEE80211_FCTL_PROTECTED)) {
/* Store CCMP PN so that we can verify that the next
* fragment has a sequential PN value. */
@@ -707,7 +704,7 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx)
if (entry->ccmp) {
int i;
u8 pn[CCMP_PN_LEN], *rpn;
- if (!rx->key || rx->key->alg != ALG_CCMP)
+ if (!rx->key || rx->key->conf.alg != ALG_CCMP)
return TXRX_DROP;
memcpy(pn, entry->last_pn, CCMP_PN_LEN);
for (i = CCMP_PN_LEN - 1; i >= 0; i--) {
@@ -900,7 +897,8 @@ ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx)
* uploaded to the hardware.
*/
if ((rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) &&
- (!rx->key || !rx->key->force_sw_encrypt))
+ (!rx->key ||
+ !(rx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)))
return TXRX_CONTINUE;
/* Drop unencrypted frames if key is set. */
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 34245b882c2..7e10c692c4a 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -228,23 +228,20 @@ void sta_info_free(struct sta_info *sta)
if (sta->key) {
if (local->ops->set_key) {
- struct ieee80211_key_conf *key;
- key = ieee80211_key_data2conf(local, sta->key);
- if (key) {
- local->ops->set_key(local_to_hw(local),
- DISABLE_KEY,
- sta->addr, key, sta->aid);
- kfree(key);
- }
+ local->ops->set_key(local_to_hw(local),
+ DISABLE_KEY, sta->addr,
+ &sta->key->conf,
+ local->default_wep_only);
}
} else if (sta->key_idx_compression != HW_KEY_IDX_INVALID) {
struct ieee80211_key_conf conf;
memset(&conf, 0, sizeof(conf));
conf.hw_key_idx = sta->key_idx_compression;
- conf.alg = ALG_NULL;
+ conf.alg = ALG_NONE;
conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
local->ops->set_key(local_to_hw(local), DISABLE_KEY,
- sta->addr, &conf, sta->aid);
+ sta->addr, &conf,
+ local->default_wep_only);
sta->key_idx_compression = HW_KEY_IDX_INVALID;
}
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index 41621720e56..b9c1d540518 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -182,7 +182,7 @@ u8 * ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key,
*pos++ = iv0;
*pos++ = iv1;
*pos++ = iv2;
- *pos++ = (key->keyidx << 6) | (1 << 5) /* Ext IV */;
+ *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */;
*pos++ = key->u.tkip.iv32 & 0xff;
*pos++ = (key->u.tkip.iv32 >> 8) & 0xff;
*pos++ = (key->u.tkip.iv32 >> 16) & 0xff;
@@ -194,7 +194,7 @@ u8 * ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key,
void ieee80211_tkip_gen_phase1key(struct ieee80211_key *key, u8 *ta,
u16 *phase1key)
{
- tkip_mixing_phase1(ta, &key->key[ALG_TKIP_TEMP_ENCR_KEY],
+ tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY],
key->u.tkip.iv32, phase1key);
}
@@ -204,12 +204,13 @@ void ieee80211_tkip_gen_rc4key(struct ieee80211_key *key, u8 *ta,
/* Calculate per-packet key */
if (key->u.tkip.iv16 == 0 || !key->u.tkip.tx_initialized) {
/* IV16 wrapped around - perform TKIP phase 1 */
- tkip_mixing_phase1(ta, &key->key[ALG_TKIP_TEMP_ENCR_KEY],
+ tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY],
key->u.tkip.iv32, key->u.tkip.p1k);
key->u.tkip.tx_initialized = 1;
}
- tkip_mixing_phase2(key->u.tkip.p1k, &key->key[ALG_TKIP_TEMP_ENCR_KEY],
+ tkip_mixing_phase2(key->u.tkip.p1k,
+ &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY],
key->u.tkip.iv16, rc4key);
}
@@ -266,7 +267,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
if (!(keyid & (1 << 5)))
return TKIP_DECRYPT_NO_EXT_IV;
- if ((keyid >> 6) != key->keyidx)
+ if ((keyid >> 6) != key->conf.keyidx)
return TKIP_DECRYPT_INVALID_KEYIDX;
if (key->u.tkip.rx_initialized[queue] &&
@@ -293,7 +294,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
key->u.tkip.iv32_rx[queue] != iv32) {
key->u.tkip.rx_initialized[queue] = 1;
/* IV16 wrapped around - perform TKIP phase 1 */
- tkip_mixing_phase1(ta, &key->key[ALG_TKIP_TEMP_ENCR_KEY],
+ tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY],
iv32, key->u.tkip.p1k_rx[queue]);
#ifdef CONFIG_TKIP_DEBUG
{
@@ -302,7 +303,8 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
" TK=", MAC_ARG(ta));
for (i = 0; i < 16; i++)
printk("%02x ",
- key->key[ALG_TKIP_TEMP_ENCR_KEY + i]);
+ key->conf.key[
+ ALG_TKIP_TEMP_ENCR_KEY + i]);
printk("\n");
printk(KERN_DEBUG "TKIP decrypt: P1K=");
for (i = 0; i < 5; i++)
@@ -313,7 +315,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
}
tkip_mixing_phase2(key->u.tkip.p1k_rx[queue],
- &key->key[ALG_TKIP_TEMP_ENCR_KEY],
+ &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY],
iv16, rc4key);
#ifdef CONFIG_TKIP_DEBUG
{
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ddb104a7016..684f928def9 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -539,11 +539,11 @@ ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx)
static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb)
{
- if (tx->key->force_sw_encrypt) {
+ if (tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) {
if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
return -1;
} else {
- tx->u.tx.control->key_idx = tx->key->hw_key_idx;
+ tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
if (tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) {
if (ieee80211_wep_add_iv(tx->local, skb, tx->key) ==
NULL)
@@ -561,7 +561,7 @@ ieee80211_tx_h_wep_encrypt(struct ieee80211_txrx_data *tx)
fc = le16_to_cpu(hdr->frame_control);
- if (!tx->key || tx->key->alg != ALG_WEP ||
+ if (!tx->key || tx->key->conf.alg != ALG_WEP ||
((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
(fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)))
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 1ad3d75281c..0b19e89fcf6 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -67,7 +67,7 @@ void ieee80211_wep_get_iv(struct ieee80211_local *local,
struct ieee80211_key *key, u8 *iv)
{
local->wep_iv++;
- if (ieee80211_wep_weak_iv(local->wep_iv, key->keylen))
+ if (ieee80211_wep_weak_iv(local->wep_iv, key->conf.keylen))
local->wep_iv += 0x0100;
if (!iv)
@@ -76,7 +76,7 @@ void ieee80211_wep_get_iv(struct ieee80211_local *local,
*iv++ = (local->wep_iv >> 16) & 0xff;
*iv++ = (local->wep_iv >> 8) & 0xff;
*iv++ = local->wep_iv & 0xff;
- *iv++ = key->keyidx << 6;
+ *iv++ = key->conf.keyidx << 6;
}
@@ -159,10 +159,10 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb,
u8 *rc4key, *iv;
size_t len;
- if (!key || key->alg != ALG_WEP)
+ if (!key || key->conf.alg != ALG_WEP)
return -1;
- klen = 3 + key->keylen;
+ klen = 3 + key->conf.keylen;
rc4key = kmalloc(klen, GFP_ATOMIC);
if (!rc4key)
return -1;
@@ -179,7 +179,7 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb,
memcpy(rc4key, iv, 3);
/* Copy rest of the WEP key (the secret part) */
- memcpy(rc4key + 3, key->key, key->keylen);
+ memcpy(rc4key + 3, key->conf.key, key->conf.keylen);
/* Add room for ICV */
skb_put(skb, WEP_ICV_LEN);
@@ -251,10 +251,10 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
keyidx = skb->data[hdrlen + 3] >> 6;
- if (!key || keyidx != key->keyidx || key->alg != ALG_WEP)
+ if (!key || keyidx != key->conf.keyidx || key->conf.alg != ALG_WEP)
return -1;
- klen = 3 + key->keylen;
+ klen = 3 + key->conf.keylen;
rc4key = kmalloc(klen, GFP_ATOMIC);
if (!rc4key)
@@ -264,7 +264,7 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
memcpy(rc4key, skb->data + hdrlen, 3);
/* Copy rest of the WEP key (the secret part) */
- memcpy(rc4key + 3, key->key, key->keylen);
+ memcpy(rc4key + 3, key->conf.key, key->conf.keylen);
if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen,
skb->data + hdrlen + WEP_IV_LEN,
@@ -321,7 +321,7 @@ u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)
ivpos = skb->data + hdrlen;
iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2];
- if (ieee80211_wep_weak_iv(iv, key->keylen))
+ if (ieee80211_wep_weak_iv(iv, key->conf.keylen))
return ivpos;
return NULL;
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 1142b42b5fe..4a2a9aa638b 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -82,14 +82,14 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx)
fc = tx->fc;
- if (!tx->key || tx->key->alg != ALG_TKIP || skb->len < 24 ||
+ if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 ||
!WLAN_FC_DATA_PRESENT(fc))
return TXRX_CONTINUE;
if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len))
return TXRX_DROP;
- if (!tx->key->force_sw_encrypt &&
+ if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) &&
!(tx->flags & IEEE80211_TXRXD_FRAGMENTED) &&
!(tx->local->hw.flags & IEEE80211_HW_TKIP_INCLUDE_MMIC) &&
!wpa_test) {
@@ -114,8 +114,8 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx)
#else
authenticator = 1;
#endif
- key = &tx->key->key[authenticator ? ALG_TKIP_TEMP_AUTH_TX_MIC_KEY :
- ALG_TKIP_TEMP_AUTH_RX_MIC_KEY];
+ key = &tx->key->conf.key[authenticator ? ALG_TKIP_TEMP_AUTH_TX_MIC_KEY :
+ ALG_TKIP_TEMP_AUTH_RX_MIC_KEY];
mic = skb_put(skb, MICHAEL_MIC_LEN);
michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic);
@@ -141,12 +141,12 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx)
if (rx->local->hw.flags & IEEE80211_HW_DEVICE_STRIPS_MIC)
return TXRX_CONTINUE;
- if (!rx->key || rx->key->alg != ALG_TKIP ||
+ if (!rx->key || rx->key->conf.alg != ALG_TKIP ||
!(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc))
return TXRX_CONTINUE;
if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
- !rx->key->force_sw_encrypt) {
+ !(rx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
if (rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) {
if (skb->len < MICHAEL_MIC_LEN)
return TXRX_DROP;
@@ -169,8 +169,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx)
#else
authenticator = 1;
#endif
- key = &rx->key->key[authenticator ? ALG_TKIP_TEMP_AUTH_RX_MIC_KEY :
- ALG_TKIP_TEMP_AUTH_TX_MIC_KEY];
+ key = &rx->key->conf.key[authenticator ? ALG_TKIP_TEMP_AUTH_RX_MIC_KEY :
+ ALG_TKIP_TEMP_AUTH_TX_MIC_KEY];
michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic);
if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) {
if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
@@ -179,7 +179,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx)
printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from "
MAC_FMT "\n", rx->dev->name, MAC_ARG(sa));
- mac80211_ev_michael_mic_failure(rx->dev, rx->key->keyidx,
+ mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx,
(void *) skb->data);
return TXRX_DROP;
}
@@ -205,7 +205,11 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx,
hdrlen = ieee80211_get_hdrlen(fc);
len = skb->len - hdrlen;
- tailneed = !tx->key->force_sw_encrypt ? 0 : TKIP_ICV_LEN;
+ if (tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)
+ tailneed = TKIP_ICV_LEN;
+ else
+ tailneed = 0;
+
if ((skb_headroom(skb) < TKIP_IV_LEN ||
skb_tailroom(skb) < tailneed)) {
I802_DEBUG_INC(tx->local->tx_expand_skb_head);
@@ -223,7 +227,7 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx,
if (key->u.tkip.iv16 == 0)
key->u.tkip.iv32++;
- if (!tx->key->force_sw_encrypt) {
+ if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
u32 flags = tx->local->hw.flags;
hdr = (struct ieee80211_hdr *)skb->data;
@@ -250,7 +254,7 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx,
~IEEE80211_TXCTL_TKIP_NEW_PHASE1_KEY;
}
- tx->u.tx.control->key_idx = tx->key->hw_key_idx;
+ tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
return 0;
}
@@ -275,18 +279,18 @@ ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx)
fc = le16_to_cpu(hdr->frame_control);
- if (!key || key->alg != ALG_TKIP || !WLAN_FC_DATA_PRESENT(fc))
+ if (!key || key->conf.alg != ALG_TKIP || !WLAN_FC_DATA_PRESENT(fc))
return TXRX_CONTINUE;
tx->u.tx.control->icv_len = TKIP_ICV_LEN;
tx->u.tx.control->iv_len = TKIP_IV_LEN;
ieee80211_tx_set_iswep(tx);
- if (!tx->key->force_sw_encrypt &&
+ if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) &&
!(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) &&
!wpa_test) {
/* hwaccel - with no need for preallocated room for IV/ICV */
- tx->u.tx.control->key_idx = tx->key->hw_key_idx;
+ tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
return TXRX_CONTINUE;
}
@@ -318,7 +322,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx)
fc = le16_to_cpu(hdr->frame_control);
hdrlen = ieee80211_get_hdrlen(fc);
- if (!rx->key || rx->key->alg != ALG_TKIP ||
+ if (!rx->key || rx->key->conf.alg != ALG_TKIP ||
!(rx->fc & IEEE80211_FCTL_PROTECTED) ||
(rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
return TXRX_CONTINUE;
@@ -327,7 +331,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx)
return TXRX_DROP;
if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
- !rx->key->force_sw_encrypt) {
+ !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
if (!(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) {
/* Hardware takes care of all processing, including
* replay protection, so no need to continue here. */
@@ -471,7 +475,10 @@ static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx,
hdrlen = ieee80211_get_hdrlen(fc);
len = skb->len - hdrlen;
- tailneed = !key->force_sw_encrypt ? 0 : CCMP_MIC_LEN;
+ if (key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)
+ tailneed = CCMP_MIC_LEN;
+ else
+ tailneed = 0;
if ((skb_headroom(skb) < CCMP_HDR_LEN ||
skb_tailroom(skb) < tailneed)) {
@@ -495,11 +502,11 @@ static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx,
break;
}
- ccmp_pn2hdr(pos, pn, key->keyidx);
+ ccmp_pn2hdr(pos, pn, key->conf.keyidx);
- if (!key->force_sw_encrypt) {
+ if (!(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
/* hwaccel - with preallocated room for CCMP header */
- tx->u.tx.control->key_idx = key->hw_key_idx;
+ tx->u.tx.control->key_idx = key->conf.hw_key_idx;
return 0;
}
@@ -523,18 +530,18 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx)
fc = le16_to_cpu(hdr->frame_control);
- if (!key || key->alg != ALG_CCMP || !WLAN_FC_DATA_PRESENT(fc))
+ if (!key || key->conf.alg != ALG_CCMP || !WLAN_FC_DATA_PRESENT(fc))
return TXRX_CONTINUE;
tx->u.tx.control->icv_len = CCMP_MIC_LEN;
tx->u.tx.control->iv_len = CCMP_HDR_LEN;
ieee80211_tx_set_iswep(tx);
- if (!tx->key->force_sw_encrypt &&
+ if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) &&
!(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) {
/* hwaccel - with no need for preallocated room for CCMP "
* header or MIC fields */
- tx->u.tx.control->key_idx = tx->key->hw_key_idx;
+ tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
return TXRX_CONTINUE;
}
@@ -569,7 +576,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
fc = le16_to_cpu(hdr->frame_control);
hdrlen = ieee80211_get_hdrlen(fc);
- if (!key || key->alg != ALG_CCMP ||
+ if (!key || key->conf.alg != ALG_CCMP ||
!(rx->fc & IEEE80211_FCTL_PROTECTED) ||
(rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
return TXRX_CONTINUE;
@@ -579,7 +586,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
return TXRX_DROP;
if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
- !key->force_sw_encrypt &&
+ !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) &&
!(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV))
return TXRX_CONTINUE;
@@ -600,7 +607,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
}
if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
- !key->force_sw_encrypt) {
+ !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
/* hwaccel has already decrypted frame and verified MIC */
} else {
u8 *scratch, *b_0, *aad;