* [PATCH 0/2] key handling improvements
@ 2007-08-16 13:53 Johannes Berg
2007-08-16 13:53 ` [PATCH 1/2] mac80211: embed key conf in key, fix driver interface Johannes Berg
2007-08-16 13:53 ` [PATCH 2/2] mac80211: revamp key handling Johannes Berg
0 siblings, 2 replies; 5+ messages in thread
From: Johannes Berg @ 2007-08-16 13:53 UTC (permalink / raw)
To: John Linville; +Cc: Jiri Benc, Michael Wu, linux-wireless
Lots of changes to the key code.
The first one makes an prototype compatible but semantically
incompatible change in the set_key() callback so it'd be good
if these could go in together to actually break out-of-tree
drivers using it.
johannes
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] mac80211: embed key conf in key, fix driver interface
2007-08-16 13:53 [PATCH 0/2] key handling improvements Johannes Berg
@ 2007-08-16 13:53 ` Johannes Berg
2007-08-17 21:02 ` Johannes Berg
2007-08-16 13:53 ` [PATCH 2/2] mac80211: revamp key handling Johannes Berg
1 sibling, 1 reply; 5+ messages in thread
From: Johannes Berg @ 2007-08-16 13:53 UTC (permalink / raw)
To: John Linville; +Cc: Jiri Benc, Michael Wu, linux-wireless
This patch embeds the struct ieee80211_key_conf into struct ieee80211_key
and thus avoids allocations and having data present twice.
This required some more changes:
1) The removal of the IEEE80211_KEY_DEFAULT_TX_KEY key flag.
This flag isn't used by drivers nor should it be since
we have a set_key_idx() callback. Maybe that callback needs
to be extended to include the key conf, but only a driver that
requires it will tell.
2) The removal of the IEEE80211_KEY_DEFAULT_WEP_ONLY key flag.
This flag is global, so it shouldn't be passed in the key
conf structure. Pass it to the function instead.
Also, this patch removes the AID parameter to the set_key() callback
because it is currently unused and the hardware currently cannot know
about the AID anyway. I suspect this was used with some hardware that
actually selected the AID itself, but that functionality was removed.
Additionally, I've removed the ALG_NULL key algorithm since we have
ALG_NONE.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
drivers/net/wireless/b43/main.c | 4 -
drivers/net/wireless/iwl-base.c | 2
include/net/mac80211.h | 51 ++++++++++--------
net/mac80211/debugfs_key.c | 56 +++++++++++++++-----
net/mac80211/ieee80211.c | 5 +
net/mac80211/ieee80211_i.h | 3 -
net/mac80211/ieee80211_iface.c | 3 -
net/mac80211/ieee80211_ioctl.c | 108 +++++++++++++++++-----------------------
net/mac80211/ieee80211_key.h | 2
net/mac80211/ieee80211_sta.c | 2
net/mac80211/key.c | 28 ----------
net/mac80211/rx.c | 17 ++----
net/mac80211/sta_info.c | 17 ++----
net/mac80211/tkip.c | 16 ++---
net/mac80211/tx.c | 6 +-
net/mac80211/wep.c | 18 +++---
net/mac80211/wpa.c | 61 ++++++++++++----------
17 files changed, 194 insertions(+), 205 deletions(-)
--- wireless-dev.orig/drivers/net/wireless/b43/main.c 2007-08-15 20:34:30.043475381 +0200
+++ wireless-dev/drivers/net/wireless/b43/main.c 2007-08-16 13:38:06.533471955 +0200
@@ -2759,7 +2759,8 @@ static int b43_dev_config(struct ieee802
static int b43_dev_set_key(struct ieee80211_hw *hw,
set_key_cmd cmd,
- u8 * addr, struct ieee80211_key_conf *key, int aid)
+ u8 * addr, struct ieee80211_key_conf *key,
+ int static_wep_only)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev = wl->current_dev;
@@ -2773,7 +2774,6 @@ static int b43_dev_set_key(struct ieee80
return -ENODEV;
switch (key->alg) {
case ALG_NONE:
- case ALG_NULL:
algorithm = B43_SEC_ALGO_NONE;
break;
case ALG_WEP:
--- wireless-dev.orig/include/net/mac80211.h 2007-08-15 20:33:00.013475381 +0200
+++ wireless-dev/include/net/mac80211.h 2007-08-16 13:38:06.633471955 +0200
@@ -203,8 +203,8 @@ struct ieee80211_tx_control {
* is not implemented by the driver */
u8 power_level; /* per-packet transmit power level, in dBm */
u8 antenna_sel_tx; /* 0 = default/diversity, 1 = Ant0, 2 = Ant1 */
- s8 key_idx; /* -1 = do not encrypt, >= 0 keyidx from
- * hw->set_key() */
+ s8 key_idx; /* HW_KEY_IDX_INVALID = do not encrypt,
+ * other values: keyidx from hw->set_key() */
u8 icv_len; /* length of the ICV/MIC field in octets */
u8 iv_len; /* length of the IV field in octets */
u8 tkip_key[16]; /* generated phase2/phase1 key for hw TKIP */
@@ -389,26 +389,23 @@ struct ieee80211_if_conf {
struct ieee80211_tx_control *beacon_control;
};
-typedef enum { ALG_NONE, ALG_WEP, ALG_TKIP, ALG_CCMP, ALG_NULL }
-ieee80211_key_alg;
-
+typedef enum {
+ ALG_NONE,
+ ALG_WEP,
+ ALG_TKIP,
+ ALG_CCMP,
+} ieee80211_key_alg;
struct ieee80211_key_conf {
+ /* shall be changed by the driver to anything but HW_KEY_IDX_INVALID */
+ int hw_key_idx;
- int hw_key_idx; /* filled + used by low-level driver */
ieee80211_key_alg alg;
+
int keylen;
#define IEEE80211_KEY_FORCE_SW_ENCRYPT (1<<0) /* to be cleared by low-level
driver */
-#define IEEE80211_KEY_DEFAULT_TX_KEY (1<<1) /* This key is the new default TX
- key (used only for broadcast
- keys). */
-#define IEEE80211_KEY_DEFAULT_WEP_ONLY (1<<2) /* static WEP is the only
- configured security policy;
- this allows some low-level
- drivers to determine when
- hwaccel can be used */
u32 flags; /* key configuration flags defined above */
s8 keyidx; /* WEP key index */
@@ -672,20 +669,26 @@ struct ieee80211_ops {
* Must be atomic. */
int (*set_tim)(struct ieee80211_hw *hw, int aid, int set);
- /* Set encryption key. IEEE 802.11 module calls this function to set
- * encryption keys. addr is ff:ff:ff:ff:ff:ff for default keys and
- * station hwaddr for individual keys. aid of the station is given
- * to help low-level driver in selecting which key->hw_key_idx to use
- * for this key. TX control data will use the hw_key_idx selected by
- * the low-level driver. */
+ /*
+ * Set encryption key.
+ *
+ * This is called to enable hardware acceleration of encryption and
+ * decryption. The address will be the broadcast address for default
+ * keys and the other station's hardware address for individual keys.
+ * When transmitting, the TX control data will use the hw_key_idx
+ * selected by the low-level driver.
+ */
int (*set_key)(struct ieee80211_hw *hw, set_key_cmd cmd,
- u8 *addr, struct ieee80211_key_conf *key, int aid);
+ u8 *address, struct ieee80211_key_conf *key,
+ int static_wep_only);
- /* Set TX key index for default/broadcast keys. This is needed in cases
+ /*
+ * Set TX key index for default/broadcast keys. This is needed in cases
* where wlan card is doing full WEP/TKIP encapsulation (wep_include_iv
* is not set), in other cases, this function pointer can be set to
- * NULL since the IEEE 802. 11 module takes care of selecting the key
- * index for each TX frame. */
+ * NULL since the IEEE 802.11 module takes care of selecting the key
+ * index for each TX frame.
+ */
int (*set_key_idx)(struct ieee80211_hw *hw, int idx);
/* Enable/disable IEEE 802.1X. This item requests wlan card to pass
--- wireless-dev.orig/net/mac80211/ieee80211_ioctl.c 2007-08-15 20:24:16.823475381 +0200
+++ wireless-dev/net/mac80211/ieee80211_ioctl.c 2007-08-16 13:38:05.953471955 +0200
@@ -280,10 +280,11 @@ static int ieee80211_ioctl_add_sta(struc
* for TX filtering. */
memset(&conf, 0, sizeof(conf));
conf.hw_key_idx = HW_KEY_IDX_INVALID;
- conf.alg = ALG_NULL;
+ conf.alg = ALG_NONE;
conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
if (local->ops->set_key(local_to_hw(local), SET_KEY,
- sta->addr, &conf, sta->aid)) {
+ sta->addr, &conf,
+ local->default_wep_only)) {
sta->key_idx_compression = HW_KEY_IDX_INVALID;
} else {
sta->key_idx_compression = conf.hw_key_idx;
@@ -397,31 +398,26 @@ int ieee80211_set_hw_encryption(struct n
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);
int rc = 0;
- /* default to sw encryption; this will be cleared by low-level
- * driver if the hw supports requested encryption */
+ /*
+ * 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 (local->ops->set_key(local_to_hw(local), SET_KEY, addr,
- keyconf, sta ? sta->aid : 0)) {
+ if (key && local->ops->set_key) {
+ rc = local->ops->set_key(local_to_hw(local), SET_KEY, addr,
+ &key->conf, local->default_wep_only);
+ if (rc) {
rc = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
- 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;
-
+ /* protect against buggy drivers */
+ key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
+ key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
}
}
- kfree(keyconf);
return rc;
}
@@ -436,7 +432,6 @@ static int ieee80211_set_encryption(stru
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);
@@ -526,20 +521,18 @@ static int ieee80211_set_encryption(stru
}
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)) {
if (err)
*err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
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);
@@ -563,22 +556,20 @@ static int ieee80211_set_encryption(stru
/* 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;
@@ -711,7 +702,7 @@ static int ieee80211_ioctl_get_encryptio
sta = NULL;
if (param->u.crypt.idx >= NUM_DEFAULT_KEYS) {
param->u.crypt.idx = sdata->default_key ?
- sdata->default_key->keyidx : 0;
+ sdata->default_key->conf.keyidx : 0;
return 0;
} else
key = &sdata->keys[param->u.crypt.idx];
@@ -731,7 +722,7 @@ static int ieee80211_ioctl_get_encryptio
param->u.crypt.key_len = 0;
param->u.crypt.idx = 0xff;
} else {
- switch ((*key)->alg) {
+ switch ((*key)->conf.alg) {
case ALG_WEP:
memcpy(param->u.crypt.alg, "WEP", 4);
break;
@@ -746,7 +737,7 @@ static int ieee80211_ioctl_get_encryptio
if (local->ops->get_sequence_counter(
local_to_hw(local),
param->sta_addr,
- (*key)->keyidx,
+ (*key)->conf.keyidx,
IEEE80211_SEQ_COUNTER_TX,
&iv32,
&iv16)) {
@@ -786,12 +777,12 @@ static int ieee80211_ioctl_get_encryptio
break;
}
- if (max_key_len < (*key)->keylen)
+ if (max_key_len < (*key)->conf.keylen)
ret = -E2BIG;
else {
- param->u.crypt.key_len = (*key)->keylen;
- memcpy(param->u.crypt.key, (*key)->key,
- (*key)->keylen);
+ param->u.crypt.key_len = (*key)->conf.keylen;
+ memcpy(param->u.crypt.key, (*key)->conf.key,
+ (*key)->conf.keylen);
}
}
@@ -1761,43 +1752,38 @@ static int ieee80211_ioctl_giwretry(stru
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;
}
@@ -2156,9 +2142,9 @@ static int ieee80211_ioctl_giwencode(str
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;
--- wireless-dev.orig/net/mac80211/sta_info.c 2007-08-15 20:34:41.963475381 +0200
+++ wireless-dev/net/mac80211/sta_info.c 2007-08-16 13:38:06.123471955 +0200
@@ -254,23 +254,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;
}
--- wireless-dev.orig/drivers/net/wireless/iwl-base.c 2007-08-16 11:55:24.713471955 +0200
+++ wireless-dev/drivers/net/wireless/iwl-base.c 2007-08-16 13:38:06.573471955 +0200
@@ -7880,7 +7880,7 @@ static int iwl_mac_hw_scan(struct ieee80
}
static int iwl_mac_set_key(struct ieee80211_hw *hw, set_key_cmd cmd, u8 *addr,
- struct ieee80211_key_conf *key, int aid)
+ struct ieee80211_key_conf *key, int static_wep_only)
{
struct iwl_priv *priv = hw->priv;
int rc = 0;
--- wireless-dev.orig/net/mac80211/debugfs_key.c 2007-08-16 11:49:05.743471955 +0200
+++ wireless-dev/net/mac80211/debugfs_key.c 2007-08-16 13:38:06.453471955 +0200
@@ -14,6 +14,35 @@
#include "debugfs.h"
#include "debugfs_key.h"
+#define KEY_CONF_READ(name, buflen, format_string) \
+static ssize_t key_conf_##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->conf.name);\
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+}
+#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);
+
+
#define KEY_READ(name, buflen, format_string) \
static ssize_t key_##name##_read(struct file *file, \
char __user *userbuf, \
@@ -36,12 +65,9 @@ static const struct file_operations key_
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);
KEY_FILE(tx_rx_count, D);
+
static ssize_t key_algorithm_read(struct file *file,
char __user *userbuf,
size_t count, loff_t *ppos)
@@ -49,7 +75,7 @@ static ssize_t key_algorithm_read(struct
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 +100,7 @@ static ssize_t key_tx_spec_read(struct f
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 +129,7 @@ static ssize_t key_rx_spec_read(struct f
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 +165,7 @@ static ssize_t key_replays_read(struct f
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 +176,12 @@ static ssize_t key_key_read(struct file
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);
@@ -175,7 +201,7 @@ void ieee80211_debugfs_key_add(struct ie
if (!local->debugfs.keys)
return;
- sprintf(buf, "%d", key->keyidx);
+ sprintf(buf, "%d", key->conf.keyidx);
key->debugfs.dir = debugfs_create_dir(buf,
local->debugfs.keys);
@@ -183,7 +209,7 @@ void ieee80211_debugfs_key_add(struct ie
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);
@@ -203,7 +229,7 @@ void ieee80211_debugfs_key_remove(struct
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);
@@ -225,7 +251,7 @@ void ieee80211_debugfs_key_add_default(s
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);
}
--- wireless-dev.orig/net/mac80211/ieee80211.c 2007-08-16 11:49:05.253471955 +0200
+++ wireless-dev/net/mac80211/ieee80211.c 2007-08-16 13:38:06.333471955 +0200
@@ -844,7 +844,7 @@ static void ieee80211_remove_tx_extra(st
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;
@@ -861,7 +861,8 @@ static void ieee80211_remove_tx_extra(st
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);
--- wireless-dev.orig/net/mac80211/ieee80211_i.h 2007-08-16 11:49:05.353471955 +0200
+++ wireless-dev/net/mac80211/ieee80211_i.h 2007-08-16 13:38:05.933471955 +0200
@@ -903,9 +903,6 @@ int ieee80211_subif_start_xmit(struct sk
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);
--- wireless-dev.orig/net/mac80211/ieee80211_key.h 2007-08-16 11:49:05.413471955 +0200
+++ wireless-dev/net/mac80211/ieee80211_key.h 2007-08-16 13:38:06.033471955 +0200
@@ -80,7 +80,7 @@ struct ieee80211_key {
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;
--- wireless-dev.orig/net/mac80211/ieee80211_sta.c 2007-08-16 11:49:05.573471955 +0200
+++ wireless-dev/net/mac80211/ieee80211_sta.c 2007-08-16 11:51:31.403471955 +0200
@@ -1345,7 +1345,7 @@ static int ieee80211_sta_wep_configured(
{
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;
}
--- wireless-dev.orig/net/mac80211/key.c 2007-08-16 11:49:05.233471955 +0200
+++ wireless-dev/net/mac80211/key.c 2007-08-16 13:38:06.063471955 +0200
@@ -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
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);
--- wireless-dev.orig/net/mac80211/rx.c 2007-08-15 20:23:18.083475381 +0200
+++ wireless-dev/net/mac80211/rx.c 2007-08-16 13:38:06.363471955 +0200
@@ -520,17 +520,14 @@ ieee80211_rx_h_wep_weak_iv_detection(str
{
if (!rx->sta || !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
(rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
- !rx->key || rx->key->alg != ALG_WEP || !rx->u.rx.ra_match)
+ !rx->key || rx->key->conf.alg != ALG_WEP || !rx->u.rx.ra_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;
}
@@ -542,7 +539,7 @@ ieee80211_rx_h_wep_decrypt(struct ieee80
if (rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP)
return TXRX_CONTINUE;
- 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 ||
@@ -557,7 +554,7 @@ ieee80211_rx_h_wep_decrypt(struct ieee80
}
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 "
@@ -681,7 +678,7 @@ ieee80211_rx_h_defragment(struct ieee802
/* 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. */
@@ -708,7 +705,7 @@ ieee80211_rx_h_defragment(struct ieee802
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--) {
--- wireless-dev.orig/net/mac80211/tkip.c 2007-08-16 11:49:05.603471955 +0200
+++ wireless-dev/net/mac80211/tkip.c 2007-08-16 11:51:31.413471955 +0200
@@ -182,7 +182,7 @@ u8 * ieee80211_tkip_add_iv(u8 *pos, stru
*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, stru
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,12 @@ void ieee80211_tkip_gen_rc4key(struct ie
/* 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 +266,7 @@ int ieee80211_tkip_decrypt_data(struct c
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 +293,7 @@ int ieee80211_tkip_decrypt_data(struct c
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 +302,7 @@ int ieee80211_tkip_decrypt_data(struct c
" 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 +313,7 @@ int ieee80211_tkip_decrypt_data(struct c
}
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
{
--- wireless-dev.orig/net/mac80211/tx.c 2007-08-16 11:49:05.703471955 +0200
+++ wireless-dev/net/mac80211/tx.c 2007-08-16 13:38:06.243471955 +0200
@@ -538,11 +538,11 @@ ieee80211_tx_h_fragment(struct ieee80211
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)
@@ -560,7 +560,7 @@ ieee80211_tx_h_wep_encrypt(struct ieee80
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)))
--- wireless-dev.orig/net/mac80211/wep.c 2007-08-16 11:49:05.493471955 +0200
+++ wireless-dev/net/mac80211/wep.c 2007-08-16 11:51:31.413471955 +0200
@@ -67,7 +67,7 @@ void ieee80211_wep_get_iv(struct ieee802
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 ieee802
*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 ieee802
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 ieee802
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 ieee802
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 ieee802
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_
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;
--- wireless-dev.orig/net/mac80211/wpa.c 2007-08-16 11:49:05.513471955 +0200
+++ wireless-dev/net/mac80211/wpa.c 2007-08-16 13:38:06.403471955 +0200
@@ -86,7 +86,7 @@ ieee80211_tx_h_michael_mic_add(struct ie
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;
@@ -101,7 +101,7 @@ ieee80211_tx_h_michael_mic_add(struct ie
}
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
- if (!tx->key->force_sw_encrypt &&
+ if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) &&
!tx->fragmented &&
!(tx->local->hw.flags & IEEE80211_HW_TKIP_INCLUDE_MMIC) &&
!wpa_test) {
@@ -126,8 +126,8 @@ ieee80211_tx_h_michael_mic_add(struct ie
#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);
@@ -172,7 +172,7 @@ ieee80211_rx_h_michael_mic_verify(struct
(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;
@@ -183,7 +183,7 @@ ieee80211_rx_h_michael_mic_verify(struct
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
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;
@@ -206,8 +206,8 @@ ieee80211_rx_h_michael_mic_verify(struct
#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);
#ifdef CONFIG_HOSTAPD_WPA_TESTING
if (rx->sta && rx->sta->wpa_trigger & WPA_TRIGGER_FAIL_RX_MIC) {
@@ -243,7 +243,7 @@ ieee80211_rx_h_michael_mic_verify(struct
printk(" (%d)\n", authenticator);
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
- 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;
}
@@ -269,7 +269,11 @@ static int tkip_encrypt_skb(struct ieee8
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);
@@ -301,7 +305,7 @@ iv_inc:
skip_iv_inc:
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
- if (!tx->key->force_sw_encrypt
+ if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)
#ifdef CONFIG_HOSTAPD_WPA_TESTING
&& !tx->wpa_test
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
@@ -332,7 +336,7 @@ skip_iv_inc:
~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;
}
@@ -357,7 +361,7 @@ ieee80211_tx_h_tkip_encrypt(struct ieee8
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;
@@ -395,11 +399,11 @@ ieee80211_tx_h_tkip_encrypt(struct ieee8
}
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
- 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;
}
@@ -454,7 +458,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee8
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;
@@ -474,7 +478,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee8
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
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. */
@@ -618,7 +622,10 @@ static int ccmp_encrypt_skb(struct ieee8
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)) {
@@ -656,11 +663,11 @@ pn_inc:
skip_pn_inc:
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
- 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;
}
@@ -684,7 +691,7 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee8
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;
#ifdef CONFIG_HOSTAPD_WPA_TESTING
@@ -712,11 +719,11 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee8
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;
}
@@ -754,7 +761,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee8
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;
@@ -764,7 +771,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee8
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;
@@ -785,7 +792,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee8
}
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;
--- wireless-dev.orig/net/mac80211/ieee80211_iface.c 2007-08-16 11:55:52.223471955 +0200
+++ wireless-dev/net/mac80211/ieee80211_iface.c 2007-08-16 13:38:06.283471955 +0200
@@ -242,7 +242,8 @@ void ieee80211_if_reinit(struct net_devi
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;
--
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] mac80211: revamp key handling
2007-08-16 13:53 [PATCH 0/2] key handling improvements Johannes Berg
2007-08-16 13:53 ` [PATCH 1/2] mac80211: embed key conf in key, fix driver interface Johannes Berg
@ 2007-08-16 13:53 ` Johannes Berg
1 sibling, 0 replies; 5+ messages in thread
From: Johannes Berg @ 2007-08-16 13:53 UTC (permalink / raw)
To: John Linville; +Cc: Jiri Benc, Michael Wu, linux-wireless
A whole bunch of things:
1) remove krefs for keys, they aren't really refcounted
2) move code and hardware acceleration handling into
key.c, weed out ieee80211_ioctl.c
3) remove the extended error codes, hostapd and wpa_supplicant
don't use them
4) remove the default_wep_only stuff, this wasn't really
done well and no current driver actually cared, allow
drivers to handle this instead by giving them access
to the local MAC address where the key should be used.
Also allow drivers to keep a list of keys and tell us that
they've had to disable a key.
5) Remove adding a fake key with a NONE key algorithm for each
associated STA. If we have hardware with such TX filtering
we should probably extend the sta_table_notification()
callback with the sta information instead; the fact that
it's treated as a key for some atheros hardware shouldn't
bother the stack.
6) Turn off hardware acceleration for keys when the interface
is down. This is necessary because otherwise monitor
interfaces could be decrypting frames for other interfaces
that are down at the moment. Also, it should go some way
towards better suspend/resume support, in any case the
routines used here could be used for that as well.
Additionally, this makes the driver interface nicer, keys
for a specific local MAC address are only ever present
while an interface with that MAC address is enabled.
7) Change driver set_key() callback interface to allow only
return values of -ENOSPC, -EOPNOTSUPP and 0, warn on all
other return values. This allows debugging the stack when
a driver notices it's handed a key while it is down.
8) Invert the flag meaning to KEY_FLAG_UPLOADED_TO_HARDWARE.
9) Update b43 and iwlwifi, but iwlwifi will give loads of
warnings because it never disables keys, I don't know the
hardware nor the driver well enough to fix that though.
10) Remove REMOVE_ALL_KEYS command as it isn't used nor do
we want to use it, we'll use DISABLE_KEY for each key.
It is hard to use REMOVE_ALL_KEYS because we can handle
multiple virtual interfaces with different key configuration,
so we'd have to keep track of a lot of state for this and
that isn't worth it.
11) Warn when disabling a key fails, it musn't.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
drivers/net/wireless/b43/main.c | 25 ---
drivers/net/wireless/iwl-base.c | 9 -
include/net/mac80211.h | 56 +++++-
net/mac80211/debugfs_key.c | 4
net/mac80211/debugfs_sta.c | 1
net/mac80211/hostapd_ioctl.h | 7
net/mac80211/ieee80211.c | 6
net/mac80211/ieee80211_i.h | 19 --
net/mac80211/ieee80211_iface.c | 25 ---
net/mac80211/ieee80211_ioctl.c | 328 +++-------------------------------------
net/mac80211/ieee80211_key.h | 28 +++
net/mac80211/key.c | 292 ++++++++++++++++++++++++++++++++++-
net/mac80211/rx.c | 4
net/mac80211/sta_info.c | 30 ---
net/mac80211/sta_info.h | 4
net/mac80211/tx.c | 9 -
net/mac80211/wpa.c | 30 +--
17 files changed, 443 insertions(+), 434 deletions(-)
--- wireless-dev.orig/net/mac80211/ieee80211_i.h 2007-08-16 13:38:05.933471955 +0200
+++ wireless-dev/net/mac80211/ieee80211_i.h 2007-08-16 13:45:40.793471955 +0200
@@ -22,6 +22,7 @@
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/etherdevice.h>
+#include <linux/mutex.h>
#include <net/wireless.h>
#include "ieee80211_key.h"
#include "sta_info.h"
@@ -308,6 +309,10 @@ struct ieee80211_sub_if_data {
struct wireless_dev wdev;
+ /* keys */
+ struct mutex key_mtx;
+ struct list_head key_list;
+
struct net_device *dev;
struct ieee80211_local *local;
@@ -607,9 +612,6 @@ struct ieee80211_local {
#endif /* CONFIG_MAC80211_DEBUG_COUNTERS */
- int default_wep_only; /* only default WEP keys are used with this
- * interface; this is used to decide when hwaccel
- * can be used with default keys */
int total_ps_buffered; /* total number of all buffered unicast and
* multicast packets for power saving stations
*/
@@ -793,12 +795,6 @@ void ieee80211_key_threshold_notify(stru
int ieee80211_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
extern const struct iw_handler_def ieee80211_iw_handler_def;
-/* Set hw encryption from ieee80211 */
-int ieee80211_set_hw_encryption(struct net_device *dev,
- struct sta_info *sta, u8 addr[ETH_ALEN],
- struct ieee80211_key *key);
-void ieee80211_update_default_wep_only(struct ieee80211_local *local);
-
/* Least common multiple of the used rates (in 100 kbps). This is used to
* calculate rate_inv values for each rate so that only integers are needed. */
@@ -902,11 +898,6 @@ int ieee80211_monitor_start_xmit(struct
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 *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);
-
/* utility functions/constants */
extern void *mac80211_wiphy_privid; /* for wiphy privid */
extern const unsigned char rfc1042_header[6];
--- wireless-dev.orig/net/mac80211/ieee80211_ioctl.c 2007-08-16 13:38:05.953471955 +0200
+++ wireless-dev/net/mac80211/ieee80211_ioctl.c 2007-08-16 13:45:40.803471955 +0200
@@ -25,7 +25,6 @@
#include "ieee80211_rate.h"
#include "wpa.h"
#include "aes_ccm.h"
-#include "debugfs_key.h"
static int ieee80211_ioctl_set_beacon(struct net_device *dev,
@@ -215,7 +214,6 @@ static int ieee80211_ioctl_add_sta(struc
int i, j;
struct ieee80211_sub_if_data *sdata;
struct ieee80211_hw_mode *mode;
- int add_key_entry = 1;
/* Prevent a race with changing the rate control algorithm */
if (!netif_running(dev))
@@ -273,24 +271,6 @@ static int ieee80211_ioctl_add_sta(struc
else
sta->flags &= ~WLAN_STA_WDS;
- if (add_key_entry && !sta->key && !sdata->default_key &&
- local->ops->set_key) {
- struct ieee80211_key_conf conf;
- /* Add key cache entry with NULL key type because this may used
- * for TX filtering. */
- memset(&conf, 0, sizeof(conf));
- conf.hw_key_idx = HW_KEY_IDX_INVALID;
- conf.alg = ALG_NONE;
- conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
- if (local->ops->set_key(local_to_hw(local), SET_KEY,
- sta->addr, &conf,
- local->default_wep_only)) {
- sta->key_idx_compression = HW_KEY_IDX_INVALID;
- } else {
- sta->key_idx_compression = conf.hw_key_idx;
- }
- }
-
sta_info_put(sta);
if (sdata->type == IEEE80211_IF_TYPE_AP)
@@ -394,44 +374,14 @@ static int ieee80211_ioctl_set_flags_sta
}
-int ieee80211_set_hw_encryption(struct net_device *dev,
- struct sta_info *sta, u8 addr[ETH_ALEN],
- struct ieee80211_key *key)
-{
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
- int rc = 0;
-
- /*
- * default to sw encryption; this will be cleared by low-level
- * driver if the hw supports requested encryption
- */
- if (key)
- key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
-
- if (key && local->ops->set_key) {
- rc = local->ops->set_key(local_to_hw(local), SET_KEY, addr,
- &key->conf, local->default_wep_only);
- if (rc) {
- rc = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
- /* protect against buggy drivers */
- key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
- key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
- }
- }
-
- return rc;
-}
-
-
static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
- int idx, int alg, int set_tx_key, u32 *err,
+ int idx, int alg, int set_tx_key,
const u8 *_key, size_t key_len)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
int ret = 0;
struct sta_info *sta;
- struct ieee80211_key *key, *old_key;
- int try_hwaccel = 1;
+ struct ieee80211_key *key;
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -464,8 +414,6 @@ static int ieee80211_set_encryption(stru
sta = sta_info_get(local, sta_addr);
if (!sta) {
- if (err)
- *err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
printk(KERN_DEBUG "%s: set_encrypt - unknown addr "
MAC_FMT "\n",
@@ -478,146 +426,27 @@ static int ieee80211_set_encryption(stru
key = sta->key;
}
- /* FIX:
- * Cannot configure default hwaccel keys with WEP algorithm, if
- * any of the virtual interfaces is using static WEP
- * configuration because hwaccel would otherwise try to decrypt
- * these frames.
- *
- * For now, just disable WEP hwaccel for broadcast when there is
- * possibility of conflict with default keys. This can maybe later be
- * optimized by using non-default keys (at least with Atheros ar521x).
- */
- if (!sta && alg == ALG_WEP && !local->default_wep_only &&
- sdata->type != IEEE80211_IF_TYPE_IBSS &&
- sdata->type != IEEE80211_IF_TYPE_AP) {
- try_hwaccel = 0;
- }
-
- if (local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) {
- /* Software encryption cannot be used with devices that hide
- * encryption from the host system, so always try to use
- * hardware acceleration with such devices. */
- try_hwaccel = 1;
- }
-
- if ((local->hw.flags & IEEE80211_HW_NO_TKIP_WMM_HWACCEL) &&
- alg == ALG_TKIP) {
- if (sta && (sta->flags & WLAN_STA_WME)) {
- /* Hardware does not support hwaccel with TKIP when using WMM.
- */
- try_hwaccel = 0;
- }
- else if (sdata->type == IEEE80211_IF_TYPE_STA) {
- sta = sta_info_get(local, sdata->u.sta.bssid);
- if (sta) {
- if (sta->flags & WLAN_STA_WME) {
- try_hwaccel = 0;
- }
- sta_info_put(sta);
- sta = NULL;
- }
- }
- }
-
if (alg == ALG_NONE) {
- if (try_hwaccel && key &&
- key->conf.hw_key_idx != HW_KEY_IDX_INVALID &&
- local->ops->set_key &&
- local->ops->set_key(local_to_hw(local), DISABLE_KEY,
- sta_addr, &key->conf,
- local->default_wep_only)) {
- if (err)
- *err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
- printk(KERN_DEBUG "%s: set_encrypt - low-level disable"
- " failed\n", dev->name);
- ret = -EINVAL;
- }
-
- if (set_tx_key || sdata->default_key == key) {
- ieee80211_debugfs_key_remove_default(sdata);
- sdata->default_key = NULL;
- }
- ieee80211_debugfs_key_remove(key);
- if (sta)
- sta->key = NULL;
- else
- sdata->keys[idx] = NULL;
ieee80211_key_free(key);
key = NULL;
} else {
- old_key = key;
- key = ieee80211_key_alloc(sta ? NULL : sdata, idx, key_len,
- GFP_KERNEL);
+ /*
+ * need to free it before allocating a new one with
+ * with the same index or debugfs messes up
+ */
+ ieee80211_key_free(key);
+ key = ieee80211_key_alloc(sdata, sta, alg, idx, key_len, _key);
if (!key) {
ret = -ENOMEM;
goto err_out;
}
-
- /* default to sw encryption; low-level driver sets these if the
- * requested encryption is supported */
- key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
- key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
-
- 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->conf.key);
- if (!key->u.ccmp.tfm) {
- ret = -ENOMEM;
- goto err_free;
- }
- }
-
- if (set_tx_key || sdata->default_key == old_key) {
- ieee80211_debugfs_key_remove_default(sdata);
- sdata->default_key = NULL;
- }
- ieee80211_debugfs_key_remove(old_key);
- if (sta)
- sta->key = key;
- else
- sdata->keys[idx] = key;
- ieee80211_key_free(old_key);
- ieee80211_debugfs_key_add(local, key);
- if (sta)
- ieee80211_debugfs_key_sta_link(key, sta);
-
- if (try_hwaccel &&
- (alg == ALG_WEP || alg == ALG_TKIP || alg == ALG_CCMP)) {
- int e = ieee80211_set_hw_encryption(dev, sta, sta_addr,
- key);
- if (err)
- *err = e;
- }
}
- if (set_tx_key || (!sta && !sdata->default_key && key)) {
- sdata->default_key = key;
- if (key)
- ieee80211_debugfs_key_add_default(sdata);
-
- if (local->ops->set_key_idx &&
- local->ops->set_key_idx(local_to_hw(local), idx))
- printk(KERN_DEBUG "%s: failed to set TX key idx for "
- "low-level driver\n", dev->name);
- }
-
- if (sta)
- sta_info_put(sta);
-
- return 0;
+ if (set_tx_key || (!sta && !sdata->default_key && key))
+ ieee80211_set_default_key(sdata, idx);
-err_free:
- ieee80211_key_free(key);
-err_out:
+ ret = 0;
+ err_out:
if (sta)
sta_info_put(sta);
return ret;
@@ -662,7 +491,6 @@ static int ieee80211_ioctl_set_encryptio
}
alg = ALG_CCMP;
} else {
- param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ALG;
printk(KERN_DEBUG "%s: set_encrypt - unknown alg\n",
dev->name);
return -EINVAL;
@@ -672,7 +500,7 @@ static int ieee80211_ioctl_set_encryptio
dev, param->sta_addr,
param->u.crypt.idx, alg,
param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY,
- ¶m->u.crypt.err, param->u.crypt.key,
+ param->u.crypt.key,
param->u.crypt.key_len);
}
@@ -684,7 +512,7 @@ static int ieee80211_ioctl_get_encryptio
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
int ret = 0;
struct sta_info *sta;
- struct ieee80211_key **key;
+ struct ieee80211_key *key;
int max_key_len;
struct ieee80211_sub_if_data *sdata;
u8 *pos;
@@ -705,24 +533,22 @@ static int ieee80211_ioctl_get_encryptio
sdata->default_key->conf.keyidx : 0;
return 0;
} else
- key = &sdata->keys[param->u.crypt.idx];
+ key = sdata->keys[param->u.crypt.idx];
} else {
sta = sta_info_get(local, param->sta_addr);
- if (!sta) {
- param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
+ if (!sta)
return -EINVAL;
- }
- key = &sta->key;
+ key = sta->key;
}
memset(param->u.crypt.seq_counter, 0, HOSTAP_SEQ_COUNTER_SIZE);
- if (!*key) {
+ if (!key) {
memcpy(param->u.crypt.alg, "none", 5);
param->u.crypt.key_len = 0;
param->u.crypt.idx = 0xff;
} else {
- switch ((*key)->conf.alg) {
+ switch (key->conf.alg) {
case ALG_WEP:
memcpy(param->u.crypt.alg, "WEP", 4);
break;
@@ -737,7 +563,7 @@ static int ieee80211_ioctl_get_encryptio
if (local->ops->get_sequence_counter(
local_to_hw(local),
param->sta_addr,
- (*key)->conf.keyidx,
+ key->conf.keyidx,
IEEE80211_SEQ_COUNTER_TX,
&iv32,
&iv16)) {
@@ -746,8 +572,8 @@ static int ieee80211_ioctl_get_encryptio
}
} else {
/* Get it from our own local data */
- iv32 = (*key)->u.tkip.iv32;
- iv16 = (*key)->u.tkip.iv16;
+ iv32 = key->u.tkip.iv32;
+ iv16 = key->u.tkip.iv16;
}
pos = param->u.crypt.seq_counter;
*pos++ = iv16 & 0xff;
@@ -763,7 +589,7 @@ static int ieee80211_ioctl_get_encryptio
u8 *pn;
memcpy(param->u.crypt.alg, "CCMP", 5);
pos = param->u.crypt.seq_counter;
- pn = (*key)->u.ccmp.tx_pn;
+ pn = key->u.ccmp.tx_pn;
*pos++ = pn[5];
*pos++ = pn[4];
*pos++ = pn[3];
@@ -777,12 +603,12 @@ static int ieee80211_ioctl_get_encryptio
break;
}
- if (max_key_len < (*key)->conf.keylen)
+ if (max_key_len < key->conf.keylen)
ret = -E2BIG;
else {
- param->u.crypt.key_len = (*key)->conf.keylen;
- memcpy(param->u.crypt.key, (*key)->conf.key,
- (*key)->conf.keylen);
+ param->u.crypt.key_len = key->conf.keylen;
+ memcpy(param->u.crypt.key, key->conf.key,
+ key->conf.keylen);
}
}
@@ -1749,95 +1575,6 @@ static int ieee80211_ioctl_giwretry(stru
return 0;
}
-static void ieee80211_key_enable_hwaccel(struct ieee80211_local *local,
- struct ieee80211_key *key)
-{
- u8 addr[ETH_ALEN];
-
- 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);
-
- if (local->ops->set_key)
- local->ops->set_key(local_to_hw(local),
- SET_KEY, addr, &key->conf,
- local->default_wep_only);
-}
-
-
-static void ieee80211_key_disable_hwaccel(struct ieee80211_local *local,
- struct ieee80211_key *key)
-{
- u8 addr[ETH_ALEN];
-
- 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);
- if (local->ops->set_key)
- local->ops->set_key(local_to_hw(local), DISABLE_KEY,
- addr, &key->conf,
- local->default_wep_only);
- key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
-}
-
-
-static int ieee80211_ioctl_default_wep_only(struct ieee80211_local *local,
- int value)
-{
- int i;
- struct ieee80211_sub_if_data *sdata;
-
- local->default_wep_only = value;
- read_lock(&local->sub_if_lock);
- list_for_each_entry(sdata, &local->sub_if_list, list)
- for (i = 0; i < NUM_DEFAULT_KEYS; i++)
- if (value)
- ieee80211_key_enable_hwaccel(local,
- sdata->keys[i]);
- else
- ieee80211_key_disable_hwaccel(local,
- sdata->keys[i]);
- read_unlock(&local->sub_if_lock);
-
- return 0;
-}
-
-
-void ieee80211_update_default_wep_only(struct ieee80211_local *local)
-{
- int i = 0;
- struct ieee80211_sub_if_data *sdata;
-
- read_lock(&local->sub_if_lock);
- list_for_each_entry(sdata, &local->sub_if_list, list) {
-
- if (sdata->dev == local->mdev)
- continue;
-
- /* If there is an AP interface then depend on userspace to
- set default_wep_only correctly. */
- if (sdata->type == IEEE80211_IF_TYPE_AP) {
- read_unlock(&local->sub_if_lock);
- return;
- }
-
- i++;
- }
-
- read_unlock(&local->sub_if_lock);
-
- if (i <= 1)
- ieee80211_ioctl_default_wep_only(local, 1);
- else
- ieee80211_ioctl_default_wep_only(local, 0);
-}
-
static int ieee80211_ioctl_prism2_param(struct net_device *dev,
struct iw_request_info *info,
@@ -2092,12 +1829,7 @@ static int ieee80211_ioctl_siwencode(str
alg = ALG_NONE;
else if (erq->length == 0) {
/* No key data - just set the default TX key index */
- if (sdata->default_key != sdata->keys[idx]) {
- ieee80211_debugfs_key_remove_default(sdata);
- sdata->default_key = sdata->keys[idx];
- if (sdata->default_key)
- ieee80211_debugfs_key_add_default(sdata);
- }
+ ieee80211_set_default_key(sdata, idx);
return 0;
}
@@ -2105,7 +1837,7 @@ static int ieee80211_ioctl_siwencode(str
dev, bcaddr,
idx, alg,
!sdata->default_key,
- NULL, keybuf, erq->length);
+ keybuf, erq->length);
}
@@ -2308,7 +2040,7 @@ static int ieee80211_ioctl_siwencodeext(
return ieee80211_set_encryption(dev, ext->addr.sa_data, idx, alg,
ext->ext_flags &
IW_ENCODE_EXT_SET_TX_KEY,
- NULL, ext->key, ext->key_len);
+ ext->key, ext->key_len);
}
--- wireless-dev.orig/net/mac80211/ieee80211_key.h 2007-08-16 13:38:06.033471955 +0200
+++ wireless-dev/net/mac80211/ieee80211_key.h 2007-08-16 14:09:43.663471955 +0200
@@ -11,7 +11,7 @@
#define IEEE80211_KEY_H
#include <linux/types.h>
-#include <linux/kref.h>
+#include <linux/list.h>
#include <linux/crypto.h>
#include <net/mac80211.h>
@@ -41,8 +41,20 @@
#define NUM_RX_DATA_QUEUES 17
+struct ieee80211_local;
+struct ieee80211_sub_if_data;
+struct sta_info;
+
+#define KEY_FLAG_UPLOADED_TO_HARDWARE (1<<0)
+
struct ieee80211_key {
- struct kref kref;
+ struct ieee80211_local *local;
+ struct ieee80211_sub_if_data *sdata;
+ struct sta_info *sta;
+
+ struct list_head list;
+
+ unsigned int flags;
union {
struct {
@@ -99,4 +111,16 @@ struct ieee80211_key {
struct ieee80211_key_conf conf;
};
+struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata,
+ struct sta_info *sta,
+ ieee80211_key_alg alg,
+ int idx,
+ size_t key_len,
+ const u8 *key_data);
+void ieee80211_key_free(struct ieee80211_key *key);
+void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx);
+void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
+void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata);
+void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata);
+
#endif /* IEEE80211_KEY_H */
--- wireless-dev.orig/net/mac80211/key.c 2007-08-16 13:38:06.063471955 +0200
+++ wireless-dev/net/mac80211/key.c 2007-08-16 14:11:03.443471955 +0200
@@ -2,42 +2,318 @@
* Copyright 2002-2005, Instant802 Networks, Inc.
* Copyright 2005-2006, Devicescape Software, Inc.
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
+ * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/if_ether.h>
+#include <linux/etherdevice.h>
+#include <linux/list.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
#include "debugfs_key.h"
#include "aes_ccm.h"
+
+/*
+ * Key handling basics
+ *
+ * Key handling in mac80211 is done based on per-interface (sub_if_data)
+ * keys and per-station keys. Since each station belongs to an interface,
+ * each station key also belongs to that interface.
+ *
+ * Hardware acceleration is done on a best-effort basis, for each key
+ * that is eligible the hardware is asked to enable that key but if
+ * it cannot do that they key is simply kept for software encryption.
+ * There is currently no way of knowing this except by looking into
+ * debugfs.
+ */
+
+static u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
+{
+ u8 *addr = bcast_addr;
+ int ret;
+
+ if (key->local->ops->set_key) {
+ int try_hwaccel = 1;
+
+ /*
+ * XXX: with the new local_mac feature most of this
+ * can probably go. Also, we should probably remove the
+ * IEEE80211_HW_NO_TKIP_WMM_HWACCEL flag and instead tell drivers
+ * with each key whether WMM might be enabled.
+ */
+
+ /* FIX:
+ * Cannot configure default hwaccel keys with WEP algorithm, if
+ * any of the virtual interfaces is using static WEP
+ * configuration because hwaccel would otherwise try to decrypt
+ * these frames.
+ *
+ * For now, just disable WEP hwaccel for broadcast when there is
+ * possibility of conflict with default keys. This can maybe later be
+ * optimized by using non-default keys (at least with Atheros ar521x).
+ */
+ if (!key->sta && key->conf.alg == ALG_WEP &&
+ key->sdata->type != IEEE80211_IF_TYPE_IBSS &&
+ key->sdata->type != IEEE80211_IF_TYPE_AP) {
+ try_hwaccel = 0;
+ }
+
+ if (key->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) {
+ /*
+ * Software encryption cannot be used with devices that
+ * hide encryption from the host system, so always try
+ * to use hardware acceleration with such devices.
+ */
+ try_hwaccel = 1;
+ }
+
+ if ((key->local->hw.flags & IEEE80211_HW_NO_TKIP_WMM_HWACCEL) &&
+ key->conf.alg == ALG_TKIP) {
+ if (key->sta && (key->sta->flags & WLAN_STA_WME)) {
+ /*
+ * Hardware does not support hwaccel
+ * with TKIP when using WMM.
+ */
+ try_hwaccel = 0;
+ }
+ else if (key->sdata->type == IEEE80211_IF_TYPE_STA) {
+ struct sta_info *sta;
+ sta = sta_info_get(key->local,
+ key->sdata->u.sta.bssid);
+ if (sta) {
+ if (sta->flags & WLAN_STA_WME)
+ try_hwaccel = 0;
+ sta_info_put(sta);
+ }
+ }
+ }
+
+ if (!try_hwaccel)
+ return;
+
+ if (key->sta)
+ addr = key->sta->addr;
+ ret = key->local->ops->set_key(local_to_hw(key->local),
+ SET_KEY,
+ key->sdata->dev->dev_addr,
+ addr, &key->conf);
+
+ WARN_ON(!ret && (key->conf.hw_key_idx == HW_KEY_IDX_INVALID));
+
+ if (!ret)
+ key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
+
+ if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP)
+ printk(KERN_ERR "mac80211-%s: failed to set key "
+ "(%d, " MAC_FMT ") to hardware (%d)\n",
+ wiphy_name(key->local->hw.wiphy),
+ key->conf.keyidx, MAC_ARG(addr), ret);
+ }
+}
+
+static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
+{
+ u8 *addr = bcast_addr;
+ int ret;
+
+ if (key->local->ops->set_key &&
+ (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
+ if (key->sta)
+ addr = key->sta->addr;
+ ret = key->local->ops->set_key(local_to_hw(key->local),
+ DISABLE_KEY,
+ key->sdata->dev->dev_addr,
+ addr, &key->conf);
+ if (ret)
+ printk(KERN_ERR "mac80211-%s: failed to remove key "
+ "(%d, " MAC_FMT ") from hardware (%d)\n",
+ wiphy_name(key->local->hw.wiphy),
+ key->conf.keyidx, MAC_ARG(addr), ret);
+
+ key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
+ key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
+ }
+}
+
+/*
+ * driver notifying us that it removed a key from hw accel,
+ * set the software key flag.
+ */
+void ieee80211_key_removed(struct ieee80211_key_conf *conf)
+{
+ struct ieee80211_key *key = container_of(conf, struct ieee80211_key,
+ conf);
+
+ WARN_ON(!conf);
+ if (!conf)
+ return;
+
+ key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
+ key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
+}
+
struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata,
- int idx, size_t key_len, gfp_t flags)
+ struct sta_info *sta,
+ ieee80211_key_alg alg,
+ int idx,
+ size_t key_len,
+ const u8 *key_data)
{
struct ieee80211_key *key;
- key = kzalloc(sizeof(struct ieee80211_key) + key_len, flags);
+ BUG_ON(alg == ALG_NONE);
+
+ key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL);
if (!key)
return NULL;
- kref_init(&key->kref);
+
+ /*
+ * Default to software encryption; we'll later upload the
+ * key to the hardware if possible.
+ */
+ key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
+ key->flags = 0;
+
+ key->conf.alg = alg;
+ key->conf.keyidx = idx;
+ key->conf.keylen = key_len;
+ memcpy(key->conf.key, key_data, key_len);
+
+ key->local = sdata->local;
+ key->sdata = sdata;
+ key->sta = sta;
+
+ 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_data);
+ if (!key->u.ccmp.tfm) {
+ ieee80211_key_free(key);
+ return NULL;
+ }
+ }
+
+ ieee80211_debugfs_key_add(key->local, key);
+
+ if (sta) {
+ ieee80211_debugfs_key_sta_link(key, sta);
+ sta->key = key;
+ } else {
+ if (idx >= 0 && idx < NUM_DEFAULT_KEYS) {
+ if (!sdata->keys[idx])
+ sdata->keys[idx] = key;
+ else
+ WARN_ON(1);
+ } else
+ WARN_ON(1);
+ }
+
+ list_add(&key->list, &sdata->key_list);
+
+ if (netif_running(key->sdata->dev))
+ ieee80211_key_enable_hw_accel(key);
+
return key;
}
-static void ieee80211_key_release(struct kref *kref)
+static void __ieee80211_key_free(struct ieee80211_key *key)
{
- struct ieee80211_key *key;
+ if (!key)
+ return;
+
+ ieee80211_key_disable_hw_accel(key);
+
+ if (key->sta) {
+ key->sta->key = NULL;
+ } else {
+ if (key->sdata->default_key == key)
+ ieee80211_set_default_key(key->sdata, -1);
+ if (key->conf.keyidx >= 0 &&
+ key->conf.keyidx < NUM_DEFAULT_KEYS)
+ key->sdata->keys[key->conf.keyidx] = NULL;
+ else
+ WARN_ON(1);
+ }
- key = container_of(kref, struct ieee80211_key, kref);
if (key->conf.alg == ALG_CCMP)
ieee80211_aes_key_free(key->u.ccmp.tfm);
ieee80211_debugfs_key_remove(key);
+
+ list_del(&key->list);
+
kfree(key);
}
void ieee80211_key_free(struct ieee80211_key *key)
{
- if (key)
- kref_put(&key->kref, ieee80211_key_release);
+ if (!key)
+ return;
+
+ mutex_lock(&key->sdata->key_mtx);
+ __ieee80211_key_free(key);
+ mutex_unlock(&key->sdata->key_mtx);
+}
+
+void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx)
+{
+ struct ieee80211_key *key = NULL;
+
+ if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
+ key = sdata->keys[idx];
+
+ if (sdata->default_key != key) {
+ ieee80211_debugfs_key_remove_default(sdata);
+
+ sdata->default_key = key;
+
+ if (sdata->default_key)
+ ieee80211_debugfs_key_add_default(sdata);
+
+ if (sdata->local->ops->set_key_idx)
+ sdata->local->ops->set_key_idx(
+ local_to_hw(sdata->local), idx);
+ }
+}
+
+void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_key *key, *tmp;
+
+ mutex_lock(&sdata->key_mtx);
+ list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
+ __ieee80211_key_free(key);
+ mutex_unlock(&sdata->key_mtx);
+}
+
+void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_key *key;
+
+ WARN_ON(!netif_running(sdata->dev));
+ if (!netif_running(sdata->dev))
+ return;
+
+ mutex_lock(&sdata->key_mtx);
+ list_for_each_entry(key, &sdata->key_list, list)
+ ieee80211_key_enable_hw_accel(key);
+ mutex_unlock(&sdata->key_mtx);
+}
+
+void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_key *key;
+
+ mutex_lock(&sdata->key_mtx);
+ list_for_each_entry(key, &sdata->key_list, list)
+ ieee80211_key_disable_hw_accel(key);
+ mutex_unlock(&sdata->key_mtx);
}
--- wireless-dev.orig/drivers/net/wireless/b43/main.c 2007-08-16 13:38:06.533471955 +0200
+++ wireless-dev/drivers/net/wireless/b43/main.c 2007-08-16 13:45:40.803471955 +0200
@@ -2758,9 +2758,8 @@ static int b43_dev_config(struct ieee802
}
static int b43_dev_set_key(struct ieee80211_hw *hw,
- set_key_cmd cmd,
- u8 * addr, struct ieee80211_key_conf *key,
- int static_wep_only)
+ set_key_cmd cmd, u8 *local_addr,
+ u8 * addr, struct ieee80211_key_conf *key)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev = wl->current_dev;
@@ -2769,7 +2768,6 @@ static int b43_dev_set_key(struct ieee80
u8 index;
int err = -EINVAL;
- key->flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
if (!dev)
return -ENODEV;
switch (key->alg) {
@@ -2807,11 +2805,10 @@ static int b43_dev_set_key(struct ieee80
switch (cmd) {
case SET_KEY:
- key->flags &= ~IEEE80211_KEY_FORCE_SW_ENCRYPT;
-
if (algorithm == B43_SEC_ALGO_TKIP) {
/* FIXME: No TKIP hardware encryption for now. */
- key->flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
+ err = -EOPNOTSUPP;
+ goto out_unlock;
}
if (is_broadcast_ether_addr(addr)) {
@@ -2822,10 +2819,8 @@ static int b43_dev_set_key(struct ieee80
err = b43_key_write(dev, -1, algorithm,
key->key, key->keylen, addr, key);
}
- if (err) {
- key->flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
+ if (err)
goto out_unlock;
- }
dev->key[key->hw_key_idx].enabled = 1;
if (algorithm == B43_SEC_ALGO_WEP40 ||
@@ -2852,10 +2847,6 @@ static int b43_dev_set_key(struct ieee80
dev->key[key->hw_key_idx].enabled = 0;
break;
}
- case REMOVE_ALL_KEYS:
- b43_clear_keys(dev);
- err = 0;
- break;
default:
B43_WARN_ON(1);
}
@@ -2864,10 +2855,10 @@ out_unlock:
mutex_unlock(&wl->mutex);
out:
if (!err) {
- bcmdbg(wl, "Using %s based encryption for keyidx: %d, "
+ bcmdbg(wl, "%s hardware based encryption for keyidx: %d, "
"mac: " MAC_FMT "\n",
- (key->flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) ?
- "software" : "hardware", key->keyidx, MAC_ARG(addr));
+ cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
+ MAC_ARG(addr));
}
return err;
}
--- wireless-dev.orig/drivers/net/wireless/iwl-base.c 2007-08-16 13:38:06.573471955 +0200
+++ wireless-dev/drivers/net/wireless/iwl-base.c 2007-08-16 13:45:40.813471955 +0200
@@ -7879,8 +7879,9 @@ static int iwl_mac_hw_scan(struct ieee80
return rc;
}
-static int iwl_mac_set_key(struct ieee80211_hw *hw, set_key_cmd cmd, u8 *addr,
- struct ieee80211_key_conf *key, int static_wep_only)
+static int iwl_mac_set_key(struct ieee80211_hw *hw, set_key_cmd cmd,
+ u8 *local_addr, u8 *addr,
+ struct ieee80211_key_conf *key)
{
struct iwl_priv *priv = hw->priv;
int rc = 0;
@@ -7897,7 +7898,7 @@ static int iwl_mac_set_key(struct ieee80
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_MAC80211("leave - " MAC_FMT
" not in station map.\n", MAC_ARG(addr));
- return -EINVAL;
+ return -ENOSPC;
}
mutex_lock(&priv->mutex);
@@ -7910,8 +7911,6 @@ static int iwl_mac_set_key(struct ieee80
if (!rc) {
iwl_set_rxon_hwcrypto(priv, 1);
iwl_commit_rxon(priv);
- key->flags &= (u32)
- (~IEEE80211_KEY_FORCE_SW_ENCRYPT);
key->hw_key_idx = sta_id;
/* TODO do we need below */
/*
--- wireless-dev.orig/net/mac80211/sta_info.c 2007-08-16 13:38:06.123471955 +0200
+++ wireless-dev/net/mac80211/sta_info.c 2007-08-16 13:45:40.813471955 +0200
@@ -19,7 +19,6 @@
#include "ieee80211_i.h"
#include "ieee80211_rate.h"
#include "sta_info.h"
-#include "debugfs_key.h"
#include "debugfs_sta.h"
/* Caller must hold local->sta_lock */
@@ -144,8 +143,6 @@ static void sta_info_release(struct kref
}
rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv);
rate_control_put(sta->rate_ctrl);
- if (sta->key)
- ieee80211_debugfs_key_sta_del(sta->key, sta);
kfree(sta);
}
@@ -191,7 +188,6 @@ struct sta_info * sta_info_add(struct ie
local->ops->sta_table_notification(local_to_hw(local),
local->num_sta);
write_unlock_bh(&local->sta_lock);
- sta->key_idx_compression = HW_KEY_IDX_INVALID;
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
printk(KERN_DEBUG "%s: Added STA " MAC_FMT "\n",
@@ -252,35 +248,13 @@ void sta_info_free(struct sta_info *sta)
dev_kfree_skb(skb);
}
- if (sta->key) {
- if (local->ops->set_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_NONE;
- conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
- local->ops->set_key(local_to_hw(local), DISABLE_KEY,
- sta->addr, &conf,
- local->default_wep_only);
- sta->key_idx_compression = HW_KEY_IDX_INVALID;
- }
-
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
printk(KERN_DEBUG "%s: Removed STA " MAC_FMT "\n",
local->mdev->name, MAC_ARG(sta->addr));
#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
- if (sta->key) {
- ieee80211_debugfs_key_remove(sta->key);
- ieee80211_key_free(sta->key);
- sta->key = NULL;
- }
+ ieee80211_key_free(sta->key);
+ sta->key = NULL;
rate_control_remove_sta_debugfs(sta);
ieee80211_sta_debugfs_remove(sta);
--- wireless-dev.orig/net/mac80211/debugfs_sta.c 2007-08-16 13:38:06.143471955 +0200
+++ wireless-dev/net/mac80211/debugfs_sta.c 2007-08-16 13:45:40.813471955 +0200
@@ -60,7 +60,6 @@ static const struct file_operations sta_
STA_OPS(name)
STA_FILE(aid, aid, D);
-STA_FILE(key_idx_compression, key_idx_compression, D);
STA_FILE(dev, dev->name, S);
STA_FILE(rx_packets, rx_packets, LU);
STA_FILE(tx_packets, tx_packets, LU);
--- wireless-dev.orig/net/mac80211/sta_info.h 2007-08-16 13:38:06.173471955 +0200
+++ wireless-dev/net/mac80211/sta_info.h 2007-08-16 13:45:40.813471955 +0200
@@ -91,10 +91,6 @@ struct sta_info {
int channel_use;
int channel_use_raw;
- int key_idx_compression; /* key table index for compression and TX
- * filtering; used only if sta->key is not
- * set */
-
unsigned int assoc_ap:1; /* whether this is an AP that we are
* associated with as a client */
unsigned int dls_sta:1; /* whether this stations is a DLS peer of us */
--- wireless-dev.orig/net/mac80211/tx.c 2007-08-16 13:38:06.243471955 +0200
+++ wireless-dev/net/mac80211/tx.c 2007-08-16 14:11:30.563471955 +0200
@@ -425,10 +425,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_t
static ieee80211_txrx_result
ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx)
{
- if (tx->sta)
- tx->u.tx.control->key_idx = tx->sta->key_idx_compression;
- else
- tx->u.tx.control->key_idx = HW_KEY_IDX_INVALID;
+ tx->u.tx.control->key_idx = HW_KEY_IDX_INVALID;
if (unlikely(tx->u.tx.control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT))
tx->key = NULL;
@@ -538,7 +535,7 @@ ieee80211_tx_h_fragment(struct ieee80211
static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb)
{
- if (tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) {
+ if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
return -1;
} else {
@@ -831,7 +828,7 @@ __ieee80211_parse_tx_radiotap(
*/
control->retry_limit = 1; /* no retry */
- control->key_idx = -1; /* no encryption key */
+ control->key_idx = HW_KEY_IDX_INVALID;
control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS |
IEEE80211_TXCTL_USE_CTS_PROTECT);
control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT |
--- wireless-dev.orig/net/mac80211/ieee80211_iface.c 2007-08-16 13:38:06.283471955 +0200
+++ wireless-dev/net/mac80211/ieee80211_iface.c 2007-08-16 13:45:40.823471955 +0200
@@ -25,6 +25,9 @@ void ieee80211_if_sdata_init(struct ieee
sdata->eapol = 1;
for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
skb_queue_head_init(&sdata->fragments[i].skb_list);
+
+ mutex_init(&sdata->key_mtx);
+ INIT_LIST_HEAD(&sdata->key_list);
}
static void ieee80211_if_sdata_deinit(struct ieee80211_sub_if_data *sdata)
@@ -88,8 +91,6 @@ int ieee80211_if_add(struct net_device *
*new_dev = ndev;
write_unlock_bh(&local->sub_if_lock);
- ieee80211_update_default_wep_only(local);
-
return 0;
fail:
@@ -154,7 +155,6 @@ void ieee80211_if_del_mgmt(struct ieee80
void ieee80211_if_set_type(struct net_device *dev, int type)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
int oldtype = sdata->type;
dev->hard_start_xmit = ieee80211_subif_start_xmit;
@@ -220,7 +220,6 @@ void ieee80211_if_set_type(struct net_de
dev->name, __FUNCTION__, type);
}
ieee80211_debugfs_change_if_type(sdata, oldtype);
- ieee80211_update_default_wep_only(local);
}
/* Must be called with rtnl lock held. */
@@ -232,21 +231,14 @@ void ieee80211_if_reinit(struct net_devi
int i;
ASSERT_RTNL();
+
+ ieee80211_free_keys(sdata);
+
ieee80211_if_sdata_deinit(sdata);
+
for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
- if (!sdata->keys[i])
- continue;
-#if 0
- /* The interface is down at the moment, so there is not
- * really much point in disabling the keys at this point. */
- memset(addr, 0xff, ETH_ALEN);
- if (local->ops->set_key)
- local->ops->set_key(local_to_hw(local), DISABLE_KEY, addr,
- local->keys[i],
- local->default_wep_only);
-#endif
ieee80211_key_free(sdata->keys[i]);
- sdata->keys[i] = NULL;
+ WARN_ON(sdata->keys[i]);
}
switch (sdata->type) {
@@ -351,7 +343,6 @@ int ieee80211_if_remove(struct net_devic
list_del(&sdata->list);
write_unlock_bh(&local->sub_if_lock);
__ieee80211_if_del(local, sdata);
- ieee80211_update_default_wep_only(local);
return 0;
}
}
--- wireless-dev.orig/include/net/mac80211.h 2007-08-16 13:38:06.633471955 +0200
+++ wireless-dev/include/net/mac80211.h 2007-08-16 14:21:40.823471955 +0200
@@ -404,11 +404,13 @@ struct ieee80211_key_conf {
int keylen;
-#define IEEE80211_KEY_FORCE_SW_ENCRYPT (1<<0) /* to be cleared by low-level
- driver */
- u32 flags; /* key configuration flags defined above */
+ /*
+ * for use by the driver, named this way to avoid
+ * accidental use in the stack
+ */
+ struct list_head driver_keylist;
- s8 keyidx; /* WEP key index */
+ s8 keyidx;
u8 key[0];
};
@@ -416,7 +418,7 @@ struct ieee80211_key_conf {
#define IEEE80211_SEQ_COUNTER_TX 1
typedef enum {
- SET_KEY, DISABLE_KEY, REMOVE_ALL_KEYS,
+ SET_KEY, DISABLE_KEY,
} set_key_cmd;
/* This is driver-visible part of the per-hw state the stack keeps. */
@@ -675,12 +677,35 @@ struct ieee80211_ops {
* This is called to enable hardware acceleration of encryption and
* decryption. The address will be the broadcast address for default
* keys and the other station's hardware address for individual keys.
+ *
+ * The local_address parameter will always be set to our own address,
+ * this is only relevant if you support multiple local addresses.
+ *
* When transmitting, the TX control data will use the hw_key_idx
* selected by the low-level driver.
+ *
+ * If you support multiple MAC addresses but only hardware acceleration
+ * based on the transmitter address, you should keep a list of all
+ * keys that are currently enabled (use the key conf's driver_keylist
+ * member) and call ieee80211_key_removed() for all keys that you had
+ * to remove.
+ * Note that you should only do that if you're unable to use the key
+ * for transmission afterwards, if you only disabled it for reception
+ * you should not call ieee80211_key_removed() because that will also
+ * remove the key for transmission.
+ *
+ * Return 0 if the key is now in use, -EOPNOTSUPP or -ENOSPC if it
+ * couldn't be added; if you return 0 then hw_key_idx must be
+ * assigned to something other than HW_KEY_IDX_INVALID. When the cmd
+ * is DISABLE_KEY then it must succeed.
+ *
+ * This callback can sleep, and is only called between add_interface
+ * and remove_interface calls, i.e. while the interface with the
+ * given local_address is enabled.
*/
int (*set_key)(struct ieee80211_hw *hw, set_key_cmd cmd,
- u8 *address, struct ieee80211_key_conf *key,
- int static_wep_only);
+ u8 *local_address, u8 *address,
+ struct ieee80211_key_conf *key);
/*
* Set TX key index for default/broadcast keys. This is needed in cases
@@ -688,6 +713,10 @@ struct ieee80211_ops {
* is not set), in other cases, this function pointer can be set to
* NULL since the IEEE 802.11 module takes care of selecting the key
* index for each TX frame.
+ *
+ * TODO: If you use this callback in your driver tell us if you need
+ * any other information from it to make it easier, like the
+ * key_conf instead.
*/
int (*set_key_idx)(struct ieee80211_hw *hw, int idx);
@@ -1081,6 +1110,19 @@ ieee80211_get_mc_list_item(struct ieee80
struct dev_mc_list *prev,
void **ptr);
+/**
+ * ieee80211_key_removed - the driver removed a key from hardware accel
+ *
+ * @keyconf: The key config structure for the key that was removed.
+ *
+ * Call this function if for some reason you had to remove a key
+ * from the hardware acceleration completely.
+ * Note that after calling this function you will not get a
+ * DISABLE_KEY notification via set_key() any more for this key,
+ * it is assumed that you've removed it already.
+ */
+void ieee80211_key_removed(struct ieee80211_key_conf *keyconf);
+
/* called by driver to notify scan status completed */
void ieee80211_scan_completed(struct ieee80211_hw *hw);
--- wireless-dev.orig/net/mac80211/ieee80211.c 2007-08-16 13:38:06.333471955 +0200
+++ wireless-dev/net/mac80211/ieee80211.c 2007-08-16 14:10:17.933471955 +0200
@@ -428,6 +428,7 @@ static int ieee80211_open(struct net_dev
ieee80211_if_config(dev);
ieee80211_reset_erp_info(dev);
+ ieee80211_enable_keys(sdata);
if (sdata->type == IEEE80211_IF_TYPE_STA &&
!local->user_space_mlme)
@@ -466,6 +467,9 @@ static int ieee80211_stop(struct net_dev
local->open_count--;
+ /* disable all keys for as long as this netdev is down */
+ ieee80211_disable_keys(sdata);
+
switch (sdata->type) {
case IEEE80211_IF_TYPE_MNTR:
local->monitors--;
@@ -862,7 +866,7 @@ static void ieee80211_remove_tx_extra(st
}
if (skb->len >= mic_len &&
- (key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT))
+ !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
skb_trim(skb, skb->len - mic_len);
if (skb->len >= iv_len && skb->len > hdrlen) {
memmove(skb->data + iv_len, skb->data, hdrlen);
--- wireless-dev.orig/net/mac80211/rx.c 2007-08-16 13:38:06.363471955 +0200
+++ wireless-dev/net/mac80211/rx.c 2007-08-16 14:11:22.353471955 +0200
@@ -525,7 +525,7 @@ ieee80211_rx_h_wep_weak_iv_detection(str
/* 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->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT))
+ !(rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
if (ieee80211_wep_is_weak_iv(rx->skb, rx->key))
rx->sta->wep_weak_iv_count++;
@@ -554,7 +554,7 @@ ieee80211_rx_h_wep_decrypt(struct ieee80
}
if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED) ||
- (rx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
+ !(rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
if (net_ratelimit())
printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
--- wireless-dev.orig/net/mac80211/wpa.c 2007-08-16 13:38:06.403471955 +0200
+++ wireless-dev/net/mac80211/wpa.c 2007-08-16 14:13:02.743471955 +0200
@@ -101,7 +101,7 @@ ieee80211_tx_h_michael_mic_add(struct ie
}
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
- if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) &&
+ if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
!tx->fragmented &&
!(tx->local->hw.flags & IEEE80211_HW_TKIP_INCLUDE_MMIC) &&
!wpa_test) {
@@ -183,7 +183,7 @@ ieee80211_rx_h_michael_mic_verify(struct
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
- !(rx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
+ (rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
if (rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) {
if (skb->len < MICHAEL_MIC_LEN)
return TXRX_DROP;
@@ -269,10 +269,10 @@ static int tkip_encrypt_skb(struct ieee8
hdrlen = ieee80211_get_hdrlen(fc);
len = skb->len - hdrlen;
- if (tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)
- tailneed = TKIP_ICV_LEN;
- else
+ if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
tailneed = 0;
+ else
+ tailneed = TKIP_ICV_LEN;
if ((skb_headroom(skb) < TKIP_IV_LEN ||
skb_tailroom(skb) < tailneed)) {
@@ -305,7 +305,7 @@ iv_inc:
skip_iv_inc:
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
- if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)
+ if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
#ifdef CONFIG_HOSTAPD_WPA_TESTING
&& !tx->wpa_test
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
@@ -399,7 +399,7 @@ ieee80211_tx_h_tkip_encrypt(struct ieee8
}
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
- if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) &&
+ if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
!(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) &&
!wpa_test) {
/* hwaccel - with no need for preallocated room for IV/ICV */
@@ -478,7 +478,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee8
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
- !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
+ (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
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. */
@@ -622,10 +622,10 @@ static int ccmp_encrypt_skb(struct ieee8
hdrlen = ieee80211_get_hdrlen(fc);
len = skb->len - hdrlen;
- if (key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)
- tailneed = CCMP_MIC_LEN;
- else
+ if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
tailneed = 0;
+ else
+ tailneed = CCMP_MIC_LEN;
if ((skb_headroom(skb) < CCMP_HDR_LEN ||
skb_tailroom(skb) < tailneed)) {
@@ -665,7 +665,7 @@ skip_pn_inc:
ccmp_pn2hdr(pos, pn, key->conf.keyidx);
- if (!(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
+ if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
/* hwaccel - with preallocated room for CCMP header */
tx->u.tx.control->key_idx = key->conf.hw_key_idx;
return 0;
@@ -719,7 +719,7 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee8
tx->u.tx.control->iv_len = CCMP_HDR_LEN;
ieee80211_tx_set_iswep(tx);
- if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) &&
+ if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
!(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) {
/* hwaccel - with no need for preallocated room for CCMP "
* header or MIC fields */
@@ -771,7 +771,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee8
return TXRX_DROP;
if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
- !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) &&
+ (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
!(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV))
return TXRX_CONTINUE;
@@ -792,7 +792,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee8
}
if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
- !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
+ (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
/* hwaccel has already decrypted frame and verified MIC */
} else {
u8 *scratch, *b_0, *aad;
--- wireless-dev.orig/net/mac80211/debugfs_key.c 2007-08-16 13:38:06.453471955 +0200
+++ wireless-dev/net/mac80211/debugfs_key.c 2007-08-16 13:45:40.823471955 +0200
@@ -25,7 +25,6 @@ static ssize_t key_conf_##name##_read(st
return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
}
#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 = { \
@@ -40,7 +39,6 @@ static const struct file_operations key_
KEY_CONF_FILE(keylen, D);
KEY_CONF_FILE(keyidx, D);
KEY_CONF_FILE(hw_key_idx, D);
-KEY_CONF_FILE(flags, X);
#define KEY_READ(name, buflen, format_string) \
@@ -54,6 +52,7 @@ static ssize_t key_##name##_read(struct
return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
}
#define KEY_READ_D(name) KEY_READ(name, 20, "%d\n")
+#define KEY_READ_X(name) KEY_READ(name, 20, "0x%x\n")
#define KEY_OPS(name) \
static const struct file_operations key_ ##name## _ops = { \
@@ -66,6 +65,7 @@ static const struct file_operations key_
KEY_OPS(name)
KEY_FILE(tx_rx_count, D);
+KEY_FILE(flags, X);
static ssize_t key_algorithm_read(struct file *file,
--- wireless-dev.orig/net/mac80211/hostapd_ioctl.h 2007-08-16 13:38:06.503471955 +0200
+++ wireless-dev/net/mac80211/hostapd_ioctl.h 2007-08-16 13:45:40.833471955 +0200
@@ -166,13 +166,6 @@ struct prism2_hostapd_param {
#define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT(0)
#define HOSTAP_CRYPT_FLAG_PERMANENT BIT(1)
-#define HOSTAP_CRYPT_ERR_UNKNOWN_ALG 2
-#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3
-#define HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED 4
-#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5
-#define HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED 6
-#define HOSTAP_CRYPT_ERR_CARD_CONF_FAILED 7
-
#define HOSTAP_HW_FLAG_NULLFUNC_OK BIT(0)
/* Data structures used for get_hw_features ioctl */
--
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] mac80211: embed key conf in key, fix driver interface
2007-08-16 13:53 ` [PATCH 1/2] mac80211: embed key conf in key, fix driver interface Johannes Berg
@ 2007-08-17 21:02 ` Johannes Berg
2007-08-17 23:30 ` [PATCH 1/2 v2] " Johannes Berg
0 siblings, 1 reply; 5+ messages in thread
From: Johannes Berg @ 2007-08-17 21:02 UTC (permalink / raw)
To: John Linville; +Cc: Jiri Benc, Michael Wu, linux-wireless
[-- Attachment #1: Type: text/plain, Size: 338 bytes --]
On Thu, 2007-08-16 at 15:53 +0200, Johannes Berg wrote:
> plain text document attachment (042-embed-key-conf.patch)
> This patch embeds the struct ieee80211_key_conf into struct ieee80211_key
> and thus avoids allocations and having data present twice.
Somehow, this missed the changes to ieee80211_key.h, I'll resend.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2 v2] mac80211: embed key conf in key, fix driver interface
2007-08-17 21:02 ` Johannes Berg
@ 2007-08-17 23:30 ` Johannes Berg
0 siblings, 0 replies; 5+ messages in thread
From: Johannes Berg @ 2007-08-17 23:30 UTC (permalink / raw)
To: John Linville; +Cc: Jiri Benc, Michael Wu, linux-wireless
This patch embeds the struct ieee80211_key_conf into struct ieee80211_key
and thus avoids allocations and having data present twice.
This required some more changes:
1) The removal of the IEEE80211_KEY_DEFAULT_TX_KEY key flag.
This flag isn't used by drivers nor should it be since
we have a set_key_idx() callback. Maybe that callback needs
to be extended to include the key conf, but only a driver that
requires it will tell.
2) The removal of the IEEE80211_KEY_DEFAULT_WEP_ONLY key flag.
This flag is global, so it shouldn't be passed in the key
conf structure. Pass it to the function instead.
Also, this patch removes the AID parameter to the set_key() callback
because it is currently unused and the hardware currently cannot know
about the AID anyway. I suspect this was used with some hardware that
actually selected the AID itself, but that functionality was removed.
Additionally, I've removed the ALG_NULL key algorithm since we have
ALG_NONE.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
drivers/net/wireless/b43/main.c | 4 -
drivers/net/wireless/iwl-base.c | 2
include/net/mac80211.h | 51 ++++++++++--------
net/mac80211/debugfs_key.c | 56 +++++++++++++++-----
net/mac80211/ieee80211.c | 5 +
net/mac80211/ieee80211_i.h | 3 -
net/mac80211/ieee80211_iface.c | 3 -
net/mac80211/ieee80211_ioctl.c | 108 +++++++++++++++++-----------------------
net/mac80211/ieee80211_key.h | 20 ++-----
net/mac80211/ieee80211_sta.c | 2
net/mac80211/key.c | 28 ----------
net/mac80211/rx.c | 17 ++----
net/mac80211/sta_info.c | 17 ++----
net/mac80211/tkip.c | 16 ++---
net/mac80211/tx.c | 6 +-
net/mac80211/wep.c | 18 +++---
net/mac80211/wpa.c | 61 ++++++++++++----------
17 files changed, 201 insertions(+), 216 deletions(-)
--- wireless-dev.orig/drivers/net/wireless/b43/main.c 2007-08-17 23:03:39.415978363 +0200
+++ wireless-dev/drivers/net/wireless/b43/main.c 2007-08-17 23:03:42.195978363 +0200
@@ -2759,7 +2759,8 @@ static int b43_dev_config(struct ieee802
static int b43_dev_set_key(struct ieee80211_hw *hw,
set_key_cmd cmd,
- u8 * addr, struct ieee80211_key_conf *key, int aid)
+ u8 * addr, struct ieee80211_key_conf *key,
+ int static_wep_only)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev = wl->current_dev;
@@ -2773,7 +2774,6 @@ static int b43_dev_set_key(struct ieee80
return -ENODEV;
switch (key->alg) {
case ALG_NONE:
- case ALG_NULL:
algorithm = B43_SEC_ALGO_NONE;
break;
case ALG_WEP:
--- wireless-dev.orig/include/net/mac80211.h 2007-08-17 23:03:39.405978363 +0200
+++ wireless-dev/include/net/mac80211.h 2007-08-17 23:03:42.195978363 +0200
@@ -203,8 +203,8 @@ struct ieee80211_tx_control {
* is not implemented by the driver */
u8 power_level; /* per-packet transmit power level, in dBm */
u8 antenna_sel_tx; /* 0 = default/diversity, 1 = Ant0, 2 = Ant1 */
- s8 key_idx; /* -1 = do not encrypt, >= 0 keyidx from
- * hw->set_key() */
+ s8 key_idx; /* HW_KEY_IDX_INVALID = do not encrypt,
+ * other values: keyidx from hw->set_key() */
u8 icv_len; /* length of the ICV/MIC field in octets */
u8 iv_len; /* length of the IV field in octets */
u8 tkip_key[16]; /* generated phase2/phase1 key for hw TKIP */
@@ -391,26 +391,23 @@ struct ieee80211_if_conf {
struct ieee80211_tx_control *beacon_control;
};
-typedef enum { ALG_NONE, ALG_WEP, ALG_TKIP, ALG_CCMP, ALG_NULL }
-ieee80211_key_alg;
-
+typedef enum {
+ ALG_NONE,
+ ALG_WEP,
+ ALG_TKIP,
+ ALG_CCMP,
+} ieee80211_key_alg;
struct ieee80211_key_conf {
+ /* shall be changed by the driver to anything but HW_KEY_IDX_INVALID */
+ int hw_key_idx;
- int hw_key_idx; /* filled + used by low-level driver */
ieee80211_key_alg alg;
+
int keylen;
#define IEEE80211_KEY_FORCE_SW_ENCRYPT (1<<0) /* to be cleared by low-level
driver */
-#define IEEE80211_KEY_DEFAULT_TX_KEY (1<<1) /* This key is the new default TX
- key (used only for broadcast
- keys). */
-#define IEEE80211_KEY_DEFAULT_WEP_ONLY (1<<2) /* static WEP is the only
- configured security policy;
- this allows some low-level
- drivers to determine when
- hwaccel can be used */
u32 flags; /* key configuration flags defined above */
s8 keyidx; /* WEP key index */
@@ -680,20 +677,26 @@ struct ieee80211_ops {
* Must be atomic. */
int (*set_tim)(struct ieee80211_hw *hw, int aid, int set);
- /* Set encryption key. IEEE 802.11 module calls this function to set
- * encryption keys. addr is ff:ff:ff:ff:ff:ff for default keys and
- * station hwaddr for individual keys. aid of the station is given
- * to help low-level driver in selecting which key->hw_key_idx to use
- * for this key. TX control data will use the hw_key_idx selected by
- * the low-level driver. */
+ /*
+ * Set encryption key.
+ *
+ * This is called to enable hardware acceleration of encryption and
+ * decryption. The address will be the broadcast address for default
+ * keys and the other station's hardware address for individual keys.
+ * When transmitting, the TX control data will use the hw_key_idx
+ * selected by the low-level driver.
+ */
int (*set_key)(struct ieee80211_hw *hw, set_key_cmd cmd,
- u8 *addr, struct ieee80211_key_conf *key, int aid);
+ u8 *address, struct ieee80211_key_conf *key,
+ int static_wep_only);
- /* Set TX key index for default/broadcast keys. This is needed in cases
+ /*
+ * Set TX key index for default/broadcast keys. This is needed in cases
* where wlan card is doing full WEP/TKIP encapsulation (wep_include_iv
* is not set), in other cases, this function pointer can be set to
- * NULL since the IEEE 802. 11 module takes care of selecting the key
- * index for each TX frame. */
+ * NULL since the IEEE 802.11 module takes care of selecting the key
+ * index for each TX frame.
+ */
int (*set_key_idx)(struct ieee80211_hw *hw, int idx);
/* Enable/disable IEEE 802.1X. This item requests wlan card to pass
--- wireless-dev.orig/net/mac80211/ieee80211_ioctl.c 2007-08-17 23:03:35.075978363 +0200
+++ wireless-dev/net/mac80211/ieee80211_ioctl.c 2007-08-17 23:03:42.205978363 +0200
@@ -280,10 +280,11 @@ static int ieee80211_ioctl_add_sta(struc
* for TX filtering. */
memset(&conf, 0, sizeof(conf));
conf.hw_key_idx = HW_KEY_IDX_INVALID;
- conf.alg = ALG_NULL;
+ conf.alg = ALG_NONE;
conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
if (local->ops->set_key(local_to_hw(local), SET_KEY,
- sta->addr, &conf, sta->aid)) {
+ sta->addr, &conf,
+ local->default_wep_only)) {
sta->key_idx_compression = HW_KEY_IDX_INVALID;
} else {
sta->key_idx_compression = conf.hw_key_idx;
@@ -398,31 +399,26 @@ int ieee80211_set_hw_encryption(struct n
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);
int rc = 0;
- /* default to sw encryption; this will be cleared by low-level
- * driver if the hw supports requested encryption */
+ /*
+ * 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 (local->ops->set_key(local_to_hw(local), SET_KEY, addr,
- keyconf, sta ? sta->aid : 0)) {
+ if (key && local->ops->set_key) {
+ rc = local->ops->set_key(local_to_hw(local), SET_KEY, addr,
+ &key->conf, local->default_wep_only);
+ if (rc) {
rc = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
- 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;
-
+ /* protect against buggy drivers */
+ key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
+ key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
}
}
- kfree(keyconf);
return rc;
}
@@ -437,7 +433,6 @@ static int ieee80211_set_encryption(stru
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);
@@ -527,20 +522,18 @@ static int ieee80211_set_encryption(stru
}
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)) {
if (err)
*err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
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);
@@ -564,22 +557,20 @@ static int ieee80211_set_encryption(stru
/* 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;
@@ -712,7 +703,7 @@ static int ieee80211_ioctl_get_encryptio
sta = NULL;
if (param->u.crypt.idx >= NUM_DEFAULT_KEYS) {
param->u.crypt.idx = sdata->default_key ?
- sdata->default_key->keyidx : 0;
+ sdata->default_key->conf.keyidx : 0;
return 0;
} else
key = &sdata->keys[param->u.crypt.idx];
@@ -732,7 +723,7 @@ static int ieee80211_ioctl_get_encryptio
param->u.crypt.key_len = 0;
param->u.crypt.idx = 0xff;
} else {
- switch ((*key)->alg) {
+ switch ((*key)->conf.alg) {
case ALG_WEP:
memcpy(param->u.crypt.alg, "WEP", 4);
break;
@@ -747,7 +738,7 @@ static int ieee80211_ioctl_get_encryptio
if (local->ops->get_sequence_counter(
local_to_hw(local),
param->sta_addr,
- (*key)->keyidx,
+ (*key)->conf.keyidx,
IEEE80211_SEQ_COUNTER_TX,
&iv32,
&iv16)) {
@@ -787,12 +778,12 @@ static int ieee80211_ioctl_get_encryptio
break;
}
- if (max_key_len < (*key)->keylen)
+ if (max_key_len < (*key)->conf.keylen)
ret = -E2BIG;
else {
- param->u.crypt.key_len = (*key)->keylen;
- memcpy(param->u.crypt.key, (*key)->key,
- (*key)->keylen);
+ param->u.crypt.key_len = (*key)->conf.keylen;
+ memcpy(param->u.crypt.key, (*key)->conf.key,
+ (*key)->conf.keylen);
}
}
@@ -1813,43 +1804,38 @@ static int ieee80211_ioctl_giwretry(stru
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;
}
@@ -2208,9 +2194,9 @@ static int ieee80211_ioctl_giwencode(str
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;
--- wireless-dev.orig/net/mac80211/sta_info.c 2007-08-17 23:03:05.885978363 +0200
+++ wireless-dev/net/mac80211/sta_info.c 2007-08-17 23:03:42.205978363 +0200
@@ -254,23 +254,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;
}
--- wireless-dev.orig/drivers/net/wireless/iwl-base.c 2007-08-17 23:03:39.425978363 +0200
+++ wireless-dev/drivers/net/wireless/iwl-base.c 2007-08-17 23:03:42.215978363 +0200
@@ -7886,7 +7886,7 @@ static int iwl_mac_hw_scan(struct ieee80
}
static int iwl_mac_set_key(struct ieee80211_hw *hw, set_key_cmd cmd, u8 *addr,
- struct ieee80211_key_conf *key, int aid)
+ struct ieee80211_key_conf *key, int static_wep_only)
{
struct iwl_priv *priv = hw->priv;
int rc = 0;
--- wireless-dev.orig/net/mac80211/debugfs_key.c 2007-08-17 23:03:41.635978363 +0200
+++ wireless-dev/net/mac80211/debugfs_key.c 2007-08-17 23:03:42.215978363 +0200
@@ -14,6 +14,35 @@
#include "debugfs.h"
#include "debugfs_key.h"
+#define KEY_CONF_READ(name, buflen, format_string) \
+static ssize_t key_conf_##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->conf.name);\
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+}
+#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);
+
+
#define KEY_READ(name, buflen, format_string) \
static ssize_t key_##name##_read(struct file *file, \
char __user *userbuf, \
@@ -36,12 +65,9 @@ static const struct file_operations key_
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);
KEY_FILE(tx_rx_count, D);
+
static ssize_t key_algorithm_read(struct file *file,
char __user *userbuf,
size_t count, loff_t *ppos)
@@ -49,7 +75,7 @@ static ssize_t key_algorithm_read(struct
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 +100,7 @@ static ssize_t key_tx_spec_read(struct f
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 +129,7 @@ static ssize_t key_rx_spec_read(struct f
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 +165,7 @@ static ssize_t key_replays_read(struct f
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 +176,12 @@ static ssize_t key_key_read(struct file
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);
@@ -175,7 +201,7 @@ void ieee80211_debugfs_key_add(struct ie
if (!local->debugfs.keys)
return;
- sprintf(buf, "%d", key->keyidx);
+ sprintf(buf, "%d", key->conf.keyidx);
key->debugfs.dir = debugfs_create_dir(buf,
local->debugfs.keys);
@@ -183,7 +209,7 @@ void ieee80211_debugfs_key_add(struct ie
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);
@@ -203,7 +229,7 @@ void ieee80211_debugfs_key_remove(struct
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);
@@ -225,7 +251,7 @@ void ieee80211_debugfs_key_add_default(s
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);
}
--- wireless-dev.orig/net/mac80211/ieee80211.c 2007-08-17 23:03:41.045978363 +0200
+++ wireless-dev/net/mac80211/ieee80211.c 2007-08-17 23:03:42.215978363 +0200
@@ -844,7 +844,7 @@ static void ieee80211_remove_tx_extra(st
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;
@@ -861,7 +861,8 @@ static void ieee80211_remove_tx_extra(st
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);
--- wireless-dev.orig/net/mac80211/ieee80211_i.h 2007-08-17 23:03:39.405978363 +0200
+++ wireless-dev/net/mac80211/ieee80211_i.h 2007-08-17 23:03:42.215978363 +0200
@@ -915,9 +915,6 @@ int ieee80211_subif_start_xmit(struct sk
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);
--- wireless-dev.orig/net/mac80211/ieee80211_key.h 2007-08-17 23:03:06.015978363 +0200
+++ wireless-dev/net/mac80211/ieee80211_key.h 2007-08-17 23:03:42.215978363 +0200
@@ -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 */
--- wireless-dev.orig/net/mac80211/ieee80211_sta.c 2007-08-17 23:03:39.505978363 +0200
+++ wireless-dev/net/mac80211/ieee80211_sta.c 2007-08-17 23:03:42.215978363 +0200
@@ -1345,7 +1345,7 @@ static int ieee80211_sta_wep_configured(
{
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;
}
--- wireless-dev.orig/net/mac80211/key.c 2007-08-17 23:03:06.115978363 +0200
+++ wireless-dev/net/mac80211/key.c 2007-08-17 23:03:42.225978363 +0200
@@ -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
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);
--- wireless-dev.orig/net/mac80211/rx.c 2007-08-17 23:03:39.405978363 +0200
+++ wireless-dev/net/mac80211/rx.c 2007-08-17 23:03:42.225978363 +0200
@@ -520,17 +520,14 @@ ieee80211_rx_h_wep_weak_iv_detection(str
{
if (!rx->sta || !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
(rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
- !rx->key || rx->key->alg != ALG_WEP || !rx->u.rx.ra_match)
+ !rx->key || rx->key->conf.alg != ALG_WEP || !rx->u.rx.ra_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;
}
@@ -542,7 +539,7 @@ ieee80211_rx_h_wep_decrypt(struct ieee80
if (rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP)
return TXRX_CONTINUE;
- 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 ||
@@ -557,7 +554,7 @@ ieee80211_rx_h_wep_decrypt(struct ieee80
}
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 "
@@ -681,7 +678,7 @@ ieee80211_rx_h_defragment(struct ieee802
/* 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. */
@@ -708,7 +705,7 @@ ieee80211_rx_h_defragment(struct ieee802
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--) {
--- wireless-dev.orig/net/mac80211/tkip.c 2007-08-17 23:03:06.165978363 +0200
+++ wireless-dev/net/mac80211/tkip.c 2007-08-17 23:03:42.225978363 +0200
@@ -182,7 +182,7 @@ u8 * ieee80211_tkip_add_iv(u8 *pos, stru
*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, stru
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,12 @@ void ieee80211_tkip_gen_rc4key(struct ie
/* 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 +266,7 @@ int ieee80211_tkip_decrypt_data(struct c
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 +293,7 @@ int ieee80211_tkip_decrypt_data(struct c
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 +302,7 @@ int ieee80211_tkip_decrypt_data(struct c
" 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 +313,7 @@ int ieee80211_tkip_decrypt_data(struct c
}
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
{
--- wireless-dev.orig/net/mac80211/tx.c 2007-08-17 23:03:30.695978363 +0200
+++ wireless-dev/net/mac80211/tx.c 2007-08-17 23:03:42.225978363 +0200
@@ -538,11 +538,11 @@ ieee80211_tx_h_fragment(struct ieee80211
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)
@@ -560,7 +560,7 @@ ieee80211_tx_h_wep_encrypt(struct ieee80
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)))
--- wireless-dev.orig/net/mac80211/wep.c 2007-08-17 23:03:06.215978363 +0200
+++ wireless-dev/net/mac80211/wep.c 2007-08-17 23:03:42.225978363 +0200
@@ -67,7 +67,7 @@ void ieee80211_wep_get_iv(struct ieee802
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 ieee802
*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 ieee802
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 ieee802
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 ieee802
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 ieee802
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_
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;
--- wireless-dev.orig/net/mac80211/wpa.c 2007-08-17 23:03:35.725978363 +0200
+++ wireless-dev/net/mac80211/wpa.c 2007-08-17 23:03:42.225978363 +0200
@@ -86,7 +86,7 @@ ieee80211_tx_h_michael_mic_add(struct ie
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;
@@ -101,7 +101,7 @@ ieee80211_tx_h_michael_mic_add(struct ie
}
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
- if (!tx->key->force_sw_encrypt &&
+ if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) &&
!tx->fragmented &&
!(tx->local->hw.flags & IEEE80211_HW_TKIP_INCLUDE_MMIC) &&
!wpa_test) {
@@ -126,8 +126,8 @@ ieee80211_tx_h_michael_mic_add(struct ie
#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);
@@ -172,7 +172,7 @@ ieee80211_rx_h_michael_mic_verify(struct
(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;
@@ -183,7 +183,7 @@ ieee80211_rx_h_michael_mic_verify(struct
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
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;
@@ -206,8 +206,8 @@ ieee80211_rx_h_michael_mic_verify(struct
#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);
#ifdef CONFIG_HOSTAPD_WPA_TESTING
if (rx->sta && rx->sta->wpa_trigger & WPA_TRIGGER_FAIL_RX_MIC) {
@@ -243,7 +243,7 @@ ieee80211_rx_h_michael_mic_verify(struct
printk(" (%d)\n", authenticator);
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
- 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;
}
@@ -269,7 +269,11 @@ static int tkip_encrypt_skb(struct ieee8
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);
@@ -301,7 +305,7 @@ iv_inc:
skip_iv_inc:
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
- if (!tx->key->force_sw_encrypt
+ if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)
#ifdef CONFIG_HOSTAPD_WPA_TESTING
&& !tx->wpa_test
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
@@ -332,7 +336,7 @@ skip_iv_inc:
~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;
}
@@ -357,7 +361,7 @@ ieee80211_tx_h_tkip_encrypt(struct ieee8
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;
@@ -395,11 +399,11 @@ ieee80211_tx_h_tkip_encrypt(struct ieee8
}
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
- 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;
}
@@ -454,7 +458,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee8
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;
@@ -474,7 +478,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee8
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
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. */
@@ -618,7 +622,10 @@ static int ccmp_encrypt_skb(struct ieee8
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)) {
@@ -656,11 +663,11 @@ pn_inc:
skip_pn_inc:
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
- 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;
}
@@ -684,7 +691,7 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee8
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;
#ifdef CONFIG_HOSTAPD_WPA_TESTING
@@ -712,11 +719,11 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee8
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;
}
@@ -754,7 +761,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee8
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;
@@ -764,7 +771,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee8
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;
@@ -785,7 +792,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee8
}
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;
--- wireless-dev.orig/net/mac80211/ieee80211_iface.c 2007-08-17 23:03:41.045978363 +0200
+++ wireless-dev/net/mac80211/ieee80211_iface.c 2007-08-17 23:03:42.235978363 +0200
@@ -244,7 +244,8 @@ void ieee80211_if_reinit(struct net_devi
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;
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2007-08-17 23:30 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-16 13:53 [PATCH 0/2] key handling improvements Johannes Berg
2007-08-16 13:53 ` [PATCH 1/2] mac80211: embed key conf in key, fix driver interface Johannes Berg
2007-08-17 21:02 ` Johannes Berg
2007-08-17 23:30 ` [PATCH 1/2 v2] " Johannes Berg
2007-08-16 13:53 ` [PATCH 2/2] mac80211: revamp key handling Johannes Berg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).