* [PATCH 1/4] nl80211: Validate MFP flag type when parsing STA flags
2009-05-11 18:57 [PATCH 0/4] nl80211/mac80211: Fix station mode key setup issues Jouni Malinen
@ 2009-05-11 18:57 ` Jouni Malinen
2009-05-11 18:57 ` [PATCH 2/4] nl80211: improve station flags handling Jouni Malinen
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Jouni Malinen @ 2009-05-11 18:57 UTC (permalink / raw)
To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen
NL80211_STA_FLAG_MFP was forgotten from sta_flags_policy. The previous
version added the flag due to the loop used in parse_station_flags,
but the proper behavior would be to allow nla_parse_nested() to go
through the policy for all flags.
Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
---
net/wireless/nl80211.c | 1 +
1 file changed, 1 insertion(+)
--- uml.orig/net/wireless/nl80211.c 2009-05-11 21:39:23.000000000 +0300
+++ uml/net/wireless/nl80211.c 2009-05-11 21:39:23.000000000 +0300
@@ -1331,6 +1331,7 @@ static const struct nla_policy sta_flags
[NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
[NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
[NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
+ [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
};
static int parse_station_flags(struct nlattr *nla, u32 *staflags)
--
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 2/4] nl80211: improve station flags handling
2009-05-11 18:57 [PATCH 0/4] nl80211/mac80211: Fix station mode key setup issues Jouni Malinen
2009-05-11 18:57 ` [PATCH 1/4] nl80211: Validate MFP flag type when parsing STA flags Jouni Malinen
@ 2009-05-11 18:57 ` Jouni Malinen
2009-05-11 18:57 ` [PATCH 3/4] nl80211: Add IEEE 802.1X PAE control for station mode Jouni Malinen
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Jouni Malinen @ 2009-05-11 18:57 UTC (permalink / raw)
To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen
From: Johannes Berg <johannes@sipsolutions.net>
It is currently not possible to modify station flags, but that
capability would be very useful. This patch introduces a new
nl80211 attribute that contains a set/mask for station flags,
and updates the internal API (and mac80211) to mirror that.
The new attribute is parsed before falling back to the old so
that userspace can specify both (if it can) to work on all
kernels.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
---
include/linux/nl80211.h | 21 ++++++++++++++++++++-
include/net/cfg80211.h | 28 +++++-----------------------
net/mac80211/cfg.c | 28 ++++++++++++++++------------
net/wireless/nl80211.c | 38 ++++++++++++++++++++++++++++++--------
4 files changed, 71 insertions(+), 44 deletions(-)
--- uml.orig/include/net/cfg80211.h 2009-05-11 21:39:21.000000000 +0300
+++ uml/include/net/cfg80211.h 2009-05-11 21:39:24.000000000 +0300
@@ -252,27 +252,6 @@ struct beacon_parameters {
};
/**
- * enum station_flags - station flags
- *
- * Station capability flags. Note that these must be the bits
- * according to the nl80211 flags.
- *
- * @STATION_FLAG_CHANGED: station flags were changed
- * @STATION_FLAG_AUTHORIZED: station is authorized to send frames (802.1X)
- * @STATION_FLAG_SHORT_PREAMBLE: station is capable of receiving frames
- * with short preambles
- * @STATION_FLAG_WME: station is WME/QoS capable
- * @STATION_FLAG_MFP: station uses management frame protection
- */
-enum station_flags {
- STATION_FLAG_CHANGED = 1<<0,
- STATION_FLAG_AUTHORIZED = 1<<NL80211_STA_FLAG_AUTHORIZED,
- STATION_FLAG_SHORT_PREAMBLE = 1<<NL80211_STA_FLAG_SHORT_PREAMBLE,
- STATION_FLAG_WME = 1<<NL80211_STA_FLAG_WME,
- STATION_FLAG_MFP = 1<<NL80211_STA_FLAG_MFP,
-};
-
-/**
* enum plink_action - actions to perform in mesh peers
*
* @PLINK_ACTION_INVALID: action 0 is reserved
@@ -294,14 +273,17 @@ enum plink_actions {
* @supported_rates: supported rates in IEEE 802.11 format
* (or NULL for no change)
* @supported_rates_len: number of supported rates
- * @station_flags: station flags (see &enum station_flags)
+ * @sta_flags_mask: station flags that changed
+ * (bitmask of BIT(NL80211_STA_FLAG_...))
+ * @sta_flags_set: station flags values
+ * (bitmask of BIT(NL80211_STA_FLAG_...))
* @listen_interval: listen interval or -1 for no change
* @aid: AID or zero for no change
*/
struct station_parameters {
u8 *supported_rates;
struct net_device *vlan;
- u32 station_flags;
+ u32 sta_flags_mask, sta_flags_set;
int listen_interval;
u16 aid;
u8 supported_rates_len;
--- uml.orig/net/wireless/nl80211.c 2009-05-11 21:39:23.000000000 +0300
+++ uml/net/wireless/nl80211.c 2009-05-11 21:39:24.000000000 +0300
@@ -123,6 +123,9 @@ static struct nla_policy nl80211_policy[
[NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
[NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
[NL80211_ATTR_USE_MFP] = { .type = NLA_U32 },
+ [NL80211_ATTR_STA_FLAGS2] = {
+ .len = sizeof(struct nl80211_sta_flag_update),
+ },
};
/* IE validation */
@@ -1334,13 +1337,33 @@ static const struct nla_policy sta_flags
[NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
};
-static int parse_station_flags(struct nlattr *nla, u32 *staflags)
+static int parse_station_flags(struct genl_info *info,
+ struct station_parameters *params)
{
struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
+ struct nlattr *nla;
int flag;
- *staflags = 0;
+ /*
+ * Try parsing the new attribute first so userspace
+ * can specify both for older kernels.
+ */
+ nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
+ if (nla) {
+ struct nl80211_sta_flag_update *sta_flags;
+
+ sta_flags = nla_data(nla);
+ params->sta_flags_mask = sta_flags->mask;
+ params->sta_flags_set = sta_flags->set;
+ if ((params->sta_flags_mask |
+ params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
+ return -EINVAL;
+ return 0;
+ }
+
+ /* if present, parse the old attribute */
+ nla = info->attrs[NL80211_ATTR_STA_FLAGS];
if (!nla)
return 0;
@@ -1348,11 +1371,12 @@ static int parse_station_flags(struct nl
nla, sta_flags_policy))
return -EINVAL;
- *staflags = STATION_FLAG_CHANGED;
+ params->sta_flags_mask = (1 << __NL80211_STA_FLAG_AFTER_LAST) - 1;
+ params->sta_flags_mask &= ~1;
for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
if (flags[flag])
- *staflags |= (1<<flag);
+ params->sta_flags_set |= (1<<flag);
return 0;
}
@@ -1648,8 +1672,7 @@ static int nl80211_set_station(struct sk
params.ht_capa =
nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
- if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
- ¶ms.station_flags))
+ if (parse_station_flags(info, ¶ms))
return -EINVAL;
if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
@@ -1718,8 +1741,7 @@ static int nl80211_new_station(struct sk
params.ht_capa =
nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
- if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
- ¶ms.station_flags))
+ if (parse_station_flags(info, ¶ms))
return -EINVAL;
rtnl_lock();
--- uml.orig/include/linux/nl80211.h 2009-05-11 21:39:13.000000000 +0300
+++ uml/include/linux/nl80211.h 2009-05-11 21:39:24.000000000 +0300
@@ -25,6 +25,8 @@
*
*/
+#include <linux/types.h>
+
/**
* DOC: Station handling
*
@@ -380,7 +382,7 @@ enum nl80211_commands {
*
* @NL80211_ATTR_STA_AID: Association ID for the station (u16)
* @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of
- * &enum nl80211_sta_flags.
+ * &enum nl80211_sta_flags (deprecated, use %NL80211_ATTR_STA_FLAGS2)
* @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by
* IEEE 802.11 7.3.1.6 (u16).
* @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported
@@ -499,6 +501,9 @@ enum nl80211_commands {
* this attribute can be used
* with %NL80211_CMD_ASSOCIATE request
*
+ * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
+ * &struct nl80211_sta_flag_update.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -603,6 +608,8 @@ enum nl80211_attrs {
NL80211_ATTR_USE_MFP,
+ NL80211_ATTR_STA_FLAGS2,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -692,6 +699,18 @@ enum nl80211_sta_flags {
};
/**
+ * struct nl80211_sta_flag_update - station flags mask/set
+ * @mask: mask of station flags to set
+ * @set: which values to set them to
+ *
+ * Both mask and set contain bits as per &enum nl80211_sta_flags.
+ */
+struct nl80211_sta_flag_update {
+ __u32 mask;
+ __u32 set;
+} __attribute__((packed));
+
+/**
* enum nl80211_rate_info - bitrate information
*
* These attribute types are used with %NL80211_STA_INFO_TXRATE
--- uml.orig/net/mac80211/cfg.c 2009-05-11 21:39:18.000000000 +0300
+++ uml/net/mac80211/cfg.c 2009-05-11 21:39:24.000000000 +0300
@@ -629,34 +629,38 @@ static void sta_apply_parameters(struct
int i, j;
struct ieee80211_supported_band *sband;
struct ieee80211_sub_if_data *sdata = sta->sdata;
+ u32 mask, set;
sband = local->hw.wiphy->bands[local->oper_channel->band];
- /*
- * FIXME: updating the flags is racy when this function is
- * called from ieee80211_change_station(), this will
- * be resolved in a future patch.
- */
+ spin_lock_bh(&sta->lock);
+ mask = params->sta_flags_mask;
+ set = params->sta_flags_set;
- if (params->station_flags & STATION_FLAG_CHANGED) {
- spin_lock_bh(&sta->lock);
+ if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
sta->flags &= ~WLAN_STA_AUTHORIZED;
- if (params->station_flags & STATION_FLAG_AUTHORIZED)
+ if (set & BIT(NL80211_STA_FLAG_AUTHORIZED))
sta->flags |= WLAN_STA_AUTHORIZED;
+ }
+ if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) {
sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
- if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE)
+ if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))
sta->flags |= WLAN_STA_SHORT_PREAMBLE;
+ }
+ if (mask & BIT(NL80211_STA_FLAG_WME)) {
sta->flags &= ~WLAN_STA_WME;
- if (params->station_flags & STATION_FLAG_WME)
+ if (set & BIT(NL80211_STA_FLAG_WME))
sta->flags |= WLAN_STA_WME;
+ }
+ if (mask & BIT(NL80211_STA_FLAG_MFP)) {
sta->flags &= ~WLAN_STA_MFP;
- if (params->station_flags & STATION_FLAG_MFP)
+ if (set & BIT(NL80211_STA_FLAG_MFP))
sta->flags |= WLAN_STA_MFP;
- spin_unlock_bh(&sta->lock);
}
+ spin_unlock_bh(&sta->lock);
/*
* FIXME: updating the following information is racy when this
--
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 3/4] nl80211: Add IEEE 802.1X PAE control for station mode
2009-05-11 18:57 [PATCH 0/4] nl80211/mac80211: Fix station mode key setup issues Jouni Malinen
2009-05-11 18:57 ` [PATCH 1/4] nl80211: Validate MFP flag type when parsing STA flags Jouni Malinen
2009-05-11 18:57 ` [PATCH 2/4] nl80211: improve station flags handling Jouni Malinen
@ 2009-05-11 18:57 ` Jouni Malinen
2009-05-11 18:57 ` [PATCH 4/4] nl80211: Add RSC configuration for new keys Jouni Malinen
2009-05-11 19:26 ` [PATCH 0/4] nl80211/mac80211: Fix station mode key setup issues Johannes Berg
4 siblings, 0 replies; 8+ messages in thread
From: Jouni Malinen @ 2009-05-11 18:57 UTC (permalink / raw)
To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen
Add a new NL80211_ATTR_CONTROL_PORT flag for NL80211_CMD_ASSOCIATE to
allow user space to indicate that it will control the IEEE 802.1X port
in station mode. Previously, mac80211 was always marking the port
authorized in station mode. This was enough when drop_unencrypted flag
was set. However, drop_unencrypted can currently be controlled only
with WEXT and the current nl80211 design does not allow fully secure
configuration. Fix this by providing a mechanism for user space to
control the IEEE 802.1X port in station mode (i.e., do the same that
we are already doing in AP mode).
Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
---
include/linux/nl80211.h | 9 +++++++++
include/net/cfg80211.h | 5 +++++
net/mac80211/cfg.c | 5 +++++
net/mac80211/ieee80211_i.h | 2 +-
net/mac80211/mlme.c | 5 +++--
net/mac80211/wext.c | 3 +++
net/wireless/nl80211.c | 3 +++
7 files changed, 29 insertions(+), 3 deletions(-)
--- uml.orig/include/linux/nl80211.h 2009-05-11 21:39:24.000000000 +0300
+++ uml/include/linux/nl80211.h 2009-05-11 21:39:26.000000000 +0300
@@ -504,6 +504,13 @@ enum nl80211_commands {
* @NL80211_ATTR_STA_FLAGS2: Attribute containing a
* &struct nl80211_sta_flag_update.
*
+ * @NL80211_ATTR_CONTROL_PORT: A flag indicating whether user space controls
+ * IEEE 802.1X port, i.e., sets/clears %NL80211_STA_FLAG_AUTHORIZED, in
+ * station mode. If the flag is included in %NL80211_CMD_ASSOCIATE
+ * request, the driver will assume that the port is unauthorized until
+ * authorized by user space. Otherwise, port is marked authorized by
+ * default in station mode.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -610,6 +617,8 @@ enum nl80211_attrs {
NL80211_ATTR_STA_FLAGS2,
+ NL80211_ATTR_CONTROL_PORT,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
--- uml.orig/include/net/cfg80211.h 2009-05-11 21:39:24.000000000 +0300
+++ uml/include/net/cfg80211.h 2009-05-11 21:39:26.000000000 +0300
@@ -655,6 +655,10 @@ struct cfg80211_auth_request {
* @ie: Extra IEs to add to (Re)Association Request frame or %NULL
* @ie_len: Length of ie buffer in octets
* @use_mfp: Use management frame protection (IEEE 802.11w) in this association
+ * @control_port: Whether user space controls IEEE 802.1X port, i.e.,
+ * sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is
+ * required to assume that the port is unauthorized until authorized by
+ * user space. Otherwise, port is marked authorized by default.
*/
struct cfg80211_assoc_request {
struct ieee80211_channel *chan;
@@ -664,6 +668,7 @@ struct cfg80211_assoc_request {
const u8 *ie;
size_t ie_len;
bool use_mfp;
+ bool control_port;
};
/**
--- uml.orig/net/mac80211/cfg.c 2009-05-11 21:39:24.000000000 +0300
+++ uml/net/mac80211/cfg.c 2009-05-11 21:39:26.000000000 +0300
@@ -1265,6 +1265,11 @@ static int ieee80211_assoc(struct wiphy
sdata->u.mgd.flags &= ~IEEE80211_STA_MFP_ENABLED;
}
+ if (req->control_port)
+ sdata->u.mgd.flags |= IEEE80211_STA_CONTROL_PORT;
+ else
+ sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
+
sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;
sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE;
ieee80211_sta_req_auth(sdata);
--- uml.orig/net/wireless/nl80211.c 2009-05-11 21:39:24.000000000 +0300
+++ uml/net/wireless/nl80211.c 2009-05-11 21:39:26.000000000 +0300
@@ -126,6 +126,7 @@ static struct nla_policy nl80211_policy[
[NL80211_ATTR_STA_FLAGS2] = {
.len = sizeof(struct nl80211_sta_flag_update),
},
+ [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
};
/* IE validation */
@@ -3040,6 +3041,8 @@ static int nl80211_associate(struct sk_b
}
}
+ req.control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
+
err = drv->ops->assoc(&drv->wiphy, dev, &req);
out:
--- uml.orig/net/mac80211/ieee80211_i.h 2009-05-11 21:39:08.000000000 +0300
+++ uml/net/mac80211/ieee80211_i.h 2009-05-11 21:39:26.000000000 +0300
@@ -235,7 +235,7 @@ struct mesh_preq_queue {
#define IEEE80211_STA_ASSOCIATED BIT(4)
#define IEEE80211_STA_PROBEREQ_POLL BIT(5)
#define IEEE80211_STA_CREATE_IBSS BIT(6)
-/* hole at 7, please re-use */
+#define IEEE80211_STA_CONTROL_PORT BIT(7)
#define IEEE80211_STA_WMM_ENABLED BIT(8)
/* hole at 9, please re-use */
#define IEEE80211_STA_AUTO_SSID_SEL BIT(10)
--- uml.orig/net/mac80211/mlme.c 2009-05-11 21:39:08.000000000 +0300
+++ uml/net/mac80211/mlme.c 2009-05-11 21:39:26.000000000 +0300
@@ -1577,8 +1577,9 @@ static void ieee80211_rx_mgmt_assoc_resp
* to between the sta_info_alloc() and sta_info_insert() above.
*/
- set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP |
- WLAN_STA_AUTHORIZED);
+ set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP);
+ if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
+ set_sta_flags(sta, WLAN_STA_AUTHORIZED);
rates = 0;
basic_rates = 0;
--- uml.orig/net/mac80211/wext.c 2009-05-11 21:39:21.000000000 +0300
+++ uml/net/mac80211/wext.c 2009-05-11 21:39:26.000000000 +0300
@@ -41,6 +41,7 @@ static int ieee80211_ioctl_siwgenie(stru
return ret;
sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
+ sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
ieee80211_sta_req_auth(sdata);
return 0;
}
@@ -124,6 +125,7 @@ static int ieee80211_ioctl_siwessid(stru
return ret;
sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
+ sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
ieee80211_sta_req_auth(sdata);
return 0;
}
@@ -181,6 +183,7 @@ static int ieee80211_ioctl_siwap(struct
if (ret)
return ret;
sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
+ sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
ieee80211_sta_req_auth(sdata);
return 0;
} else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
--
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 4/4] nl80211: Add RSC configuration for new keys
2009-05-11 18:57 [PATCH 0/4] nl80211/mac80211: Fix station mode key setup issues Jouni Malinen
` (2 preceding siblings ...)
2009-05-11 18:57 ` [PATCH 3/4] nl80211: Add IEEE 802.1X PAE control for station mode Jouni Malinen
@ 2009-05-11 18:57 ` Jouni Malinen
2009-05-13 23:38 ` Johannes Berg
2009-05-11 19:26 ` [PATCH 0/4] nl80211/mac80211: Fix station mode key setup issues Johannes Berg
4 siblings, 1 reply; 8+ messages in thread
From: Jouni Malinen @ 2009-05-11 18:57 UTC (permalink / raw)
To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen
When setting a key with NL80211_CMD_NEW_KEY, we should allow the key
sequence number (RSC) to be set in order to allow replay protection to
work correctly for group keys. This patch documents this use for
nl80211 and adds the couple of missing pieces in nl80211/cfg80211 and
mac80211 to support this. In addition, WEXT SIOCSIWENCODEEXT compat
processing in cfg80211 is extended to handle the RSC (this was already
specified in WEXT, but just not implemented in cfg80211/mac80211).
Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
---
include/linux/nl80211.h | 4 ++--
net/mac80211/cfg.c | 3 ++-
net/mac80211/key.c | 21 ++++++++++++++++++++-
net/mac80211/key.h | 3 ++-
net/wireless/nl80211.c | 5 +++++
net/wireless/wext-compat.c | 5 +++++
6 files changed, 36 insertions(+), 5 deletions(-)
--- uml.orig/include/linux/nl80211.h 2009-05-11 21:39:26.000000000 +0300
+++ uml/include/linux/nl80211.h 2009-05-11 21:39:27.000000000 +0300
@@ -79,8 +79,8 @@
* @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT,
* %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD.
* @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA,
- * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC and %NL80211_ATTR_KEY_CIPHER
- * attributes.
+ * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER,
+ * and %NL80211_ATTR_KEY_SEQ attributes.
* @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX
* or %NL80211_ATTR_MAC.
*
--- uml.orig/net/wireless/nl80211.c 2009-05-11 21:39:26.000000000 +0300
+++ uml/net/wireless/nl80211.c 2009-05-11 21:39:27.000000000 +0300
@@ -1115,6 +1115,11 @@ static int nl80211_new_key(struct sk_buf
params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
}
+ if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
+ params.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
+ params.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
+ }
+
if (info->attrs[NL80211_ATTR_KEY_IDX])
key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
--- uml.orig/net/mac80211/cfg.c 2009-05-11 21:39:26.000000000 +0300
+++ uml/net/mac80211/cfg.c 2009-05-11 21:39:27.000000000 +0300
@@ -141,7 +141,8 @@ static int ieee80211_add_key(struct wiph
return -EINVAL;
}
- key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key);
+ key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key,
+ params->seq_len, params->seq);
if (!key)
return -ENOMEM;
--- uml.orig/net/mac80211/key.c 2009-05-11 21:39:08.000000000 +0300
+++ uml/net/mac80211/key.c 2009-05-11 21:39:27.000000000 +0300
@@ -290,9 +290,11 @@ static void __ieee80211_key_replace(stru
struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
int idx,
size_t key_len,
- const u8 *key_data)
+ const u8 *key_data,
+ size_t seq_len, const u8 *seq)
{
struct ieee80211_key *key;
+ int i, j;
BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS);
@@ -318,14 +320,31 @@ struct ieee80211_key *ieee80211_key_allo
case ALG_TKIP:
key->conf.iv_len = TKIP_IV_LEN;
key->conf.icv_len = TKIP_ICV_LEN;
+ if (seq && seq_len == 6) {
+ for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
+ key->u.tkip.rx[i].iv32 =
+ get_unaligned_le32(&seq[2]);
+ key->u.tkip.rx[i].iv16 =
+ get_unaligned_le16(seq);
+ }
+ }
break;
case ALG_CCMP:
key->conf.iv_len = CCMP_HDR_LEN;
key->conf.icv_len = CCMP_MIC_LEN;
+ if (seq && seq_len == CCMP_PN_LEN) {
+ for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
+ for (j = 0; j < CCMP_PN_LEN; j++)
+ key->u.ccmp.rx_pn[i][j] =
+ seq[CCMP_PN_LEN - j - 1];
+ }
break;
case ALG_AES_CMAC:
key->conf.iv_len = 0;
key->conf.icv_len = sizeof(struct ieee80211_mmie);
+ if (seq && seq_len == 6)
+ for (j = 0; j < 6; j++)
+ key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1];
break;
}
memcpy(key->conf.key, key_data, key_len);
--- uml.orig/net/mac80211/key.h 2009-05-11 21:39:08.000000000 +0300
+++ uml/net/mac80211/key.h 2009-05-11 21:39:27.000000000 +0300
@@ -144,7 +144,8 @@ struct ieee80211_key {
struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
int idx,
size_t key_len,
- const u8 *key_data);
+ const u8 *key_data,
+ size_t seq_len, const u8 *seq);
/*
* Insert a key into data structures (sdata, sta if necessary)
* to make it used, free old key.
--- uml.orig/net/wireless/wext-compat.c 2009-05-11 21:39:21.000000000 +0300
+++ uml/net/wireless/wext-compat.c 2009-05-11 21:39:27.000000000 +0300
@@ -655,6 +655,11 @@ int cfg80211_wext_siwencodeext(struct ne
params.key_len = ext->key_len;
params.cipher = cipher;
+ if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+ params.seq = ext->rx_seq;
+ params.seq_len = 6;
+ }
+
return cfg80211_set_encryption(
rdev, dev, addr, remove,
ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
--
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 0/4] nl80211/mac80211: Fix station mode key setup issues
2009-05-11 18:57 [PATCH 0/4] nl80211/mac80211: Fix station mode key setup issues Jouni Malinen
` (3 preceding siblings ...)
2009-05-11 18:57 ` [PATCH 4/4] nl80211: Add RSC configuration for new keys Jouni Malinen
@ 2009-05-11 19:26 ` Johannes Berg
2009-05-11 19:38 ` Jouni Malinen
4 siblings, 1 reply; 8+ messages in thread
From: Johannes Berg @ 2009-05-11 19:26 UTC (permalink / raw)
To: Jouni Malinen; +Cc: John W. Linville, linux-wireless
[-- Attachment #1: Type: text/plain, Size: 929 bytes --]
On Mon, 2009-05-11 at 21:57 +0300, Jouni Malinen wrote:
> When using nl80211, we cannot currently set drop_unencrypted flag that
> was used with WEXT to avoid need for IEEE 802.1X port control in station
> mode. Because of this, we cannot currently set the keys in a secure way.
> In addition, we do not support setting the expected RSC for keys either
> with WEXT or nl80211 which is needed to avoid leaving a window for
> replaying broadcast frames.
>
> This set of patches addresses these issues and allows nl80211 to
> securely set up keys in station mode. This is on top of the pending
> MFP patches, RX-drop-unencrypted-based-on-key-setup, and WEXT key
> handling to cfg80211 patches (from Johannes).
Looks good to me, thanks. One thing I'm not sure about though, is there
no need to push the RSC to hardware for some hw crypto designs? But even
if needed that can always be a separate patch.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 0/4] nl80211/mac80211: Fix station mode key setup issues
2009-05-11 19:26 ` [PATCH 0/4] nl80211/mac80211: Fix station mode key setup issues Johannes Berg
@ 2009-05-11 19:38 ` Jouni Malinen
0 siblings, 0 replies; 8+ messages in thread
From: Jouni Malinen @ 2009-05-11 19:38 UTC (permalink / raw)
To: Johannes Berg; +Cc: Jouni Malinen, John W. Linville, linux-wireless
On Mon, May 11, 2009 at 09:26:58PM +0200, Johannes Berg wrote:
> Looks good to me, thanks. One thing I'm not sure about though, is there
> no need to push the RSC to hardware for some hw crypto designs? But even
> if needed that can always be a separate patch.
There probably would be for drivers that take care of replay protection
(which should be identifiable by searching for RX_FLAG_IV_STRIPPED). It
looks like we have couple of such drivers. However, I'm not familiar
with any of those, so someone more familiar with the driver code and
hardware/firmware design should take a look.
As an example, drivers/net/wireless/wl12xx/acx.h seems to define a
set_key structure (struct acx_set_key) that includes fields for RSC.
However, the values seem to be defined based on TKIP, so I don't know
how they would be used for CCMP (and not even the byte order that would
be used for TKIP). In other words, this type of cases will require
proper testing to make sure that we do not break frame reception
completely.
Anyway, it sounds reasonable to add rsc into struct ieee80211_key_conf
to provide this information for the driver. That should be a relatively
simple patch to add the RSC field into struct ieee80211_key_conf and
fill it with the initial value in ieee80211_key_alloc(). This will waste
some memory per key, but is likely the simplest way of implementing
this.
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply [flat|nested] 8+ messages in thread