Skip to content

Commit

Permalink
[PATCH] mac80211: consolidate decryption
Browse files Browse the repository at this point in the history
Currently, we run through all three crypto algorithms for each
received frame even though we have previously determined which
key we have and as such already know which algorithm will be
used. Change it to invoke only the needed function. Also move
the WEP decrypt handler to wep.c so that fewer functions need
to be non-static.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Johannes Berg authored and David S. Miller committed Oct 10, 2007
1 parent b2e7771 commit 4f0d18e
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 43 deletions.
40 changes: 17 additions & 23 deletions net/mac80211/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -662,36 +662,32 @@ ieee80211_rx_h_wep_weak_iv_detection(struct ieee80211_txrx_data *rx)
}

static ieee80211_txrx_result
ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx)
ieee80211_rx_h_decrypt(struct ieee80211_txrx_data *rx)
{
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 ||
(rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)))
if (!(rx->fc & IEEE80211_FCTL_PROTECTED))
return TXRX_CONTINUE;

if (!rx->key) {
if (net_ratelimit())
printk(KERN_DEBUG "%s: RX WEP frame, but no key set\n",
rx->dev->name);
printk(KERN_DEBUG "%s: RX protected frame,"
" but have no key\n", rx->dev->name);
return TXRX_DROP;
}

if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) {
if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
if (net_ratelimit())
printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
"failed\n", rx->dev->name);
return TXRX_DROP;
}
} else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) {
ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
/* remove ICV */
skb_trim(rx->skb, rx->skb->len - 4);
switch (rx->key->conf.alg) {
case ALG_WEP:
return ieee80211_crypto_wep_decrypt(rx);
case ALG_TKIP:
return ieee80211_crypto_tkip_decrypt(rx);
case ALG_CCMP:
return ieee80211_crypto_ccmp_decrypt(rx);
case ALG_NONE:
return TXRX_CONTINUE;
}

return TXRX_CONTINUE;
/* not reached */
WARN_ON(1);
return TXRX_DROP;
}

static inline struct ieee80211_fragment_entry *
Expand Down Expand Up @@ -1371,10 +1367,8 @@ ieee80211_rx_handler ieee80211_rx_handlers[] =
ieee80211_rx_h_check,
ieee80211_rx_h_load_key,
ieee80211_rx_h_sta_process,
ieee80211_rx_h_ccmp_decrypt,
ieee80211_rx_h_tkip_decrypt,
ieee80211_rx_h_wep_weak_iv_detection,
ieee80211_rx_h_wep_decrypt,
ieee80211_rx_h_decrypt,
ieee80211_rx_h_defragment,
ieee80211_rx_h_ps_poll,
ieee80211_rx_h_michael_mic_verify,
Expand Down
34 changes: 29 additions & 5 deletions net/mac80211/wep.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ static inline int ieee80211_wep_weak_iv(u32 iv, int keylen)
}


void ieee80211_wep_get_iv(struct ieee80211_local *local,
struct ieee80211_key *key, u8 *iv)
static void ieee80211_wep_get_iv(struct ieee80211_local *local,
struct ieee80211_key *key, u8 *iv)
{
local->wep_iv++;
if (ieee80211_wep_weak_iv(local->wep_iv, key->conf.keylen))
Expand Down Expand Up @@ -109,9 +109,9 @@ u8 * ieee80211_wep_add_iv(struct ieee80211_local *local,
}


void ieee80211_wep_remove_iv(struct ieee80211_local *local,
struct sk_buff *skb,
struct ieee80211_key *key)
static void ieee80211_wep_remove_iv(struct ieee80211_local *local,
struct sk_buff *skb,
struct ieee80211_key *key)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
u16 fc;
Expand Down Expand Up @@ -326,3 +326,27 @@ u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)

return NULL;
}

ieee80211_txrx_result
ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx)
{
if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
(rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH))
return TXRX_CONTINUE;

if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) {
if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
if (net_ratelimit())
printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
"failed\n", rx->dev->name);
return TXRX_DROP;
}
} else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) {
ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
/* remove ICV */
skb_trim(rx->skb, rx->skb->len - 4);
}

return TXRX_CONTINUE;
}
8 changes: 3 additions & 5 deletions net/mac80211/wep.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,9 @@

int ieee80211_wep_init(struct ieee80211_local *local);
void ieee80211_wep_free(struct ieee80211_local *local);
void ieee80211_wep_get_iv(struct ieee80211_local *local,
struct ieee80211_key *key, u8 *iv);
u8 * ieee80211_wep_add_iv(struct ieee80211_local *local,
struct sk_buff *skb,
struct ieee80211_key *key);
void ieee80211_wep_remove_iv(struct ieee80211_local *local,
struct sk_buff *skb,
struct ieee80211_key *key);
void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
size_t klen, u8 *data, size_t data_len);
int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
Expand All @@ -37,4 +32,7 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
int ieee80211_wep_get_keyidx(struct sk_buff *skb);
u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);

ieee80211_txrx_result
ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx);

#endif /* WEP_H */
12 changes: 4 additions & 8 deletions net/mac80211/wpa.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx)


ieee80211_txrx_result
ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx)
ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
u16 fc;
Expand All @@ -293,9 +293,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx)
fc = le16_to_cpu(hdr->frame_control);
hdrlen = ieee80211_get_hdrlen(fc);

if (!rx->key || rx->key->conf.alg != ALG_TKIP ||
!(rx->fc & IEEE80211_FCTL_PROTECTED) ||
(rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
return TXRX_CONTINUE;

if (!rx->sta || skb->len - hdrlen < 12)
Expand Down Expand Up @@ -535,7 +533,7 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx)


ieee80211_txrx_result
ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
u16 fc;
Expand All @@ -549,9 +547,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
fc = le16_to_cpu(hdr->frame_control);
hdrlen = ieee80211_get_hdrlen(fc);

if (!key || key->conf.alg != ALG_CCMP ||
!(rx->fc & IEEE80211_FCTL_PROTECTED) ||
(rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
return TXRX_CONTINUE;

data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN;
Expand Down
4 changes: 2 additions & 2 deletions net/mac80211/wpa.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx);
ieee80211_txrx_result
ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx);
ieee80211_txrx_result
ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx);
ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx);

ieee80211_txrx_result
ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx);
ieee80211_txrx_result
ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx);
ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx);

#endif /* WPA_H */

0 comments on commit 4f0d18e

Please sign in to comment.