diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2007-12-18 09:27:47 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:59:53 -0500 |
commit | 176e4f84423af3105894a7d71b23c1a16678a6be (patch) | |
tree | 7f5103c2ca716bd2ab2bbdb68ae024d189d5c9d7 | |
parent | 7bbdd2d987971f9d123a2db89ed921bf02e34f9a (diff) |
mac80211: move tx crypto decision
This patch moves the decision making about whether a frame is encrypted
with a certain algorithm up into the TX handlers rather than having it
in the crypto algorithm implementation.
This fixes a problem with the radiotap injection code where injecting
a non-data packet and requesting encryption could end up asking the
driver to encrypt a packet without giving it a key.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/mac80211/tx.c | 39 | ||||
-rw-r--r-- | net/mac80211/wep.c | 10 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 14 |
3 files changed, 22 insertions, 41 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index f7aff2e97ee..8302c70da9a 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -438,11 +438,7 @@ static ieee80211_txrx_result | |||
438 | ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx) | 438 | ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx) |
439 | { | 439 | { |
440 | struct ieee80211_key *key; | 440 | struct ieee80211_key *key; |
441 | const struct ieee80211_hdr *hdr; | 441 | u16 fc = tx->fc; |
442 | u16 fc; | ||
443 | |||
444 | hdr = (const struct ieee80211_hdr *) tx->skb->data; | ||
445 | fc = le16_to_cpu(hdr->frame_control); | ||
446 | 442 | ||
447 | if (unlikely(tx->u.tx.control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) | 443 | if (unlikely(tx->u.tx.control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) |
448 | tx->key = NULL; | 444 | tx->key = NULL; |
@@ -455,16 +451,34 @@ ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx) | |||
455 | !(tx->flags & IEEE80211_TXRXD_TX_INJECTED)) { | 451 | !(tx->flags & IEEE80211_TXRXD_TX_INJECTED)) { |
456 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); | 452 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); |
457 | return TXRX_DROP; | 453 | return TXRX_DROP; |
458 | } else { | 454 | } else |
459 | tx->key = NULL; | 455 | tx->key = NULL; |
460 | tx->u.tx.control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | ||
461 | } | ||
462 | 456 | ||
463 | if (tx->key) { | 457 | if (tx->key) { |
458 | u16 ftype, stype; | ||
459 | |||
464 | tx->key->tx_rx_count++; | 460 | tx->key->tx_rx_count++; |
465 | /* TODO: add threshold stuff again */ | 461 | /* TODO: add threshold stuff again */ |
462 | |||
463 | switch (tx->key->conf.alg) { | ||
464 | case ALG_WEP: | ||
465 | ftype = fc & IEEE80211_FCTL_FTYPE; | ||
466 | stype = fc & IEEE80211_FCTL_STYPE; | ||
467 | |||
468 | if (ftype == IEEE80211_FTYPE_MGMT && | ||
469 | stype == IEEE80211_STYPE_AUTH) | ||
470 | break; | ||
471 | case ALG_TKIP: | ||
472 | case ALG_CCMP: | ||
473 | if (!WLAN_FC_DATA_PRESENT(fc)) | ||
474 | tx->key = NULL; | ||
475 | break; | ||
476 | } | ||
466 | } | 477 | } |
467 | 478 | ||
479 | if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | ||
480 | tx->u.tx.control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | ||
481 | |||
468 | return TXRX_CONTINUE; | 482 | return TXRX_CONTINUE; |
469 | } | 483 | } |
470 | 484 | ||
@@ -706,15 +720,6 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) | |||
706 | } | 720 | } |
707 | } | 721 | } |
708 | 722 | ||
709 | /* | ||
710 | * Tell hardware to not encrypt when we had sw crypto. | ||
711 | * Because we use the same flag to internally indicate that | ||
712 | * no (software) encryption should be done, we have to set it | ||
713 | * after all crypto handlers. | ||
714 | */ | ||
715 | if (tx->key && !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | ||
716 | tx->u.tx.control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | ||
717 | |||
718 | return TXRX_CONTINUE; | 723 | return TXRX_CONTINUE; |
719 | } | 724 | } |
720 | 725 | ||
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index b5f3413403b..a0cff72a580 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c | |||
@@ -349,16 +349,6 @@ static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb) | |||
349 | ieee80211_txrx_result | 349 | ieee80211_txrx_result |
350 | ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx) | 350 | ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx) |
351 | { | 351 | { |
352 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; | ||
353 | u16 fc; | ||
354 | |||
355 | fc = le16_to_cpu(hdr->frame_control); | ||
356 | |||
357 | if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && | ||
358 | ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || | ||
359 | (fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH))) | ||
360 | return TXRX_CONTINUE; | ||
361 | |||
362 | tx->u.tx.control->iv_len = WEP_IV_LEN; | 352 | tx->u.tx.control->iv_len = WEP_IV_LEN; |
363 | tx->u.tx.control->icv_len = WEP_ICV_LEN; | 353 | tx->u.tx.control->icv_len = WEP_ICV_LEN; |
364 | ieee80211_tx_set_iswep(tx); | 354 | ieee80211_tx_set_iswep(tx); |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 20cec1cb956..6f04311cf0a 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -245,16 +245,9 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx, | |||
245 | ieee80211_txrx_result | 245 | ieee80211_txrx_result |
246 | ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx) | 246 | ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx) |
247 | { | 247 | { |
248 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; | ||
249 | u16 fc; | ||
250 | struct sk_buff *skb = tx->skb; | 248 | struct sk_buff *skb = tx->skb; |
251 | int wpa_test = 0, test = 0; | 249 | int wpa_test = 0, test = 0; |
252 | 250 | ||
253 | fc = le16_to_cpu(hdr->frame_control); | ||
254 | |||
255 | if (!WLAN_FC_DATA_PRESENT(fc)) | ||
256 | return TXRX_CONTINUE; | ||
257 | |||
258 | tx->u.tx.control->icv_len = TKIP_ICV_LEN; | 251 | tx->u.tx.control->icv_len = TKIP_ICV_LEN; |
259 | tx->u.tx.control->iv_len = TKIP_IV_LEN; | 252 | tx->u.tx.control->iv_len = TKIP_IV_LEN; |
260 | ieee80211_tx_set_iswep(tx); | 253 | ieee80211_tx_set_iswep(tx); |
@@ -501,16 +494,9 @@ static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx, | |||
501 | ieee80211_txrx_result | 494 | ieee80211_txrx_result |
502 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx) | 495 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx) |
503 | { | 496 | { |
504 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; | ||
505 | u16 fc; | ||
506 | struct sk_buff *skb = tx->skb; | 497 | struct sk_buff *skb = tx->skb; |
507 | int test = 0; | 498 | int test = 0; |
508 | 499 | ||
509 | fc = le16_to_cpu(hdr->frame_control); | ||
510 | |||
511 | if (!WLAN_FC_DATA_PRESENT(fc)) | ||
512 | return TXRX_CONTINUE; | ||
513 | |||
514 | tx->u.tx.control->icv_len = CCMP_MIC_LEN; | 500 | tx->u.tx.control->icv_len = CCMP_MIC_LEN; |
515 | tx->u.tx.control->iv_len = CCMP_HDR_LEN; | 501 | tx->u.tx.control->iv_len = CCMP_HDR_LEN; |
516 | ieee80211_tx_set_iswep(tx); | 502 | ieee80211_tx_set_iswep(tx); |