Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 237022
b: refs/heads/master
c: 681d119
h: refs/heads/master
v: v3
  • Loading branch information
Jouni Malinen authored and John W. Linville committed Feb 3, 2011
1 parent a628d12 commit b42534b
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 747d753df7fea1d2d29c5c33623f6d2e5d0ed2d6
refs/heads/master: 681d119047761cc59a15c0bb86891f3a878997cf
4 changes: 4 additions & 0 deletions trunk/include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,9 @@ struct ieee80211_bss_conf {
* the off-channel channel when a remain-on-channel offload is done
* in hardware -- normal packets still flow and are expected to be
* handled properly by the device.
* @IEEE80211_TX_INTFL_TKIP_MIC_FAILURE: Marks this packet to be used for TKIP
* testing. It will be sent out with incorrect Michael MIC key to allow
* TKIP countermeasures to be tested.
*
* Note: If you have to add new flags to the enumeration, then don't
* forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary.
Expand Down Expand Up @@ -370,6 +373,7 @@ enum mac80211_tx_control_flags {
IEEE80211_TX_CTL_LDPC = BIT(22),
IEEE80211_TX_CTL_STBC = BIT(23) | BIT(24),
IEEE80211_TX_CTL_TX_OFFCHAN = BIT(25),
IEEE80211_TX_INTFL_TKIP_MIC_FAILURE = BIT(26),
};

#define IEEE80211_TX_CTL_STBC_SHIFT 23
Expand Down
102 changes: 101 additions & 1 deletion trunk/net/mac80211/debugfs_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ static ssize_t ieee80211_if_read(
ret = (*format)(sdata, buf, sizeof(buf));
read_unlock(&dev_base_lock);

if (ret != -EINVAL)
if (ret >= 0)
ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret);

return ret;
Expand Down Expand Up @@ -221,6 +221,104 @@ static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata,

__IEEE80211_IF_FILE_W(smps);

static ssize_t ieee80211_if_fmt_tkip_mic_test(
const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
{
return -EOPNOTSUPP;
}

static int hwaddr_aton(const char *txt, u8 *addr)
{
int i;

for (i = 0; i < ETH_ALEN; i++) {
int a, b;

a = hex_to_bin(*txt++);
if (a < 0)
return -1;
b = hex_to_bin(*txt++);
if (b < 0)
return -1;
*addr++ = (a << 4) | b;
if (i < 5 && *txt++ != ':')
return -1;
}

return 0;
}

static ssize_t ieee80211_if_parse_tkip_mic_test(
struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
{
struct ieee80211_local *local = sdata->local;
u8 addr[ETH_ALEN];
struct sk_buff *skb;
struct ieee80211_hdr *hdr;
__le16 fc;

/*
* Assume colon-delimited MAC address with possible white space
* following.
*/
if (buflen < 3 * ETH_ALEN - 1)
return -EINVAL;
if (hwaddr_aton(buf, addr) < 0)
return -EINVAL;

if (!ieee80211_sdata_running(sdata))
return -ENOTCONN;

skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24 + 100);
if (!skb)
return -ENOMEM;
skb_reserve(skb, local->hw.extra_tx_headroom);

hdr = (struct ieee80211_hdr *) skb_put(skb, 24);
memset(hdr, 0, 24);
fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);

switch (sdata->vif.type) {
case NL80211_IFTYPE_AP:
fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
/* DA BSSID SA */
memcpy(hdr->addr1, addr, ETH_ALEN);
memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
memcpy(hdr->addr3, sdata->vif.addr, ETH_ALEN);
break;
case NL80211_IFTYPE_STATION:
fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
/* BSSID SA DA */
if (sdata->vif.bss_conf.bssid == NULL) {
dev_kfree_skb(skb);
return -ENOTCONN;
}
memcpy(hdr->addr1, sdata->vif.bss_conf.bssid, ETH_ALEN);
memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
memcpy(hdr->addr3, addr, ETH_ALEN);
break;
default:
dev_kfree_skb(skb);
return -EOPNOTSUPP;
}
hdr->frame_control = fc;

/*
* Add some length to the test frame to make it look bit more valid.
* The exact contents does not matter since the recipient is required
* to drop this because of the Michael MIC failure.
*/
memset(skb_put(skb, 50), 0, 50);

IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_TKIP_MIC_FAILURE;

ieee80211_tx_skb(sdata, skb);

return buflen;
}

__IEEE80211_IF_FILE_W(tkip_mic_test);

/* AP attributes */
IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC);
Expand Down Expand Up @@ -299,6 +397,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
DEBUGFS_ADD(last_beacon);
DEBUGFS_ADD(ave_beacon);
DEBUGFS_ADD_MODE(smps, 0600);
DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
}

static void add_ap_files(struct ieee80211_sub_if_data *sdata)
Expand All @@ -313,6 +412,7 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata)
DEBUGFS_ADD(num_sta_ps);
DEBUGFS_ADD(dtim_count);
DEBUGFS_ADD(num_buffered_multicast);
DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
}

static void add_wds_files(struct ieee80211_sub_if_data *sdata)
Expand Down
7 changes: 7 additions & 0 deletions trunk/net/mac80211/wpa.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
data = skb->data + hdrlen;
data_len = skb->len - hdrlen;

if (unlikely(info->flags & IEEE80211_TX_INTFL_TKIP_MIC_FAILURE)) {
/* Need to use software crypto for the test */
info->control.hw_key = NULL;
}

if (info->control.hw_key &&
!(tx->flags & IEEE80211_TX_FRAGMENTED) &&
!(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) {
Expand All @@ -64,6 +69,8 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
key = &tx->key->conf.key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY];
mic = skb_put(skb, MICHAEL_MIC_LEN);
michael_mic(key, hdr, data, data_len, mic);
if (unlikely(info->flags & IEEE80211_TX_INTFL_TKIP_MIC_FAILURE))
mic[0]++;

return TX_CONTINUE;
}
Expand Down

0 comments on commit b42534b

Please sign in to comment.