Commit 176e4f84423af3105894a7d71b23c1a16678a6be
Committed by
David S. Miller
1 parent
7bbdd2d987
Exists in
master
and in
7 other branches
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>
Showing 3 changed files with 22 additions and 41 deletions Side-by-side Diff
net/mac80211/tx.c
... | ... | @@ -438,12 +438,8 @@ |
438 | 438 | ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx) |
439 | 439 | { |
440 | 440 | struct ieee80211_key *key; |
441 | - const struct ieee80211_hdr *hdr; | |
442 | - u16 fc; | |
441 | + u16 fc = tx->fc; | |
443 | 442 | |
444 | - hdr = (const struct ieee80211_hdr *) tx->skb->data; | |
445 | - fc = le16_to_cpu(hdr->frame_control); | |
446 | - | |
447 | 443 | if (unlikely(tx->u.tx.control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) |
448 | 444 | tx->key = NULL; |
449 | 445 | else if (tx->sta && (key = rcu_dereference(tx->sta->key))) |
450 | 446 | |
451 | 447 | |
452 | 448 | |
453 | 449 | |
... | ... | @@ -455,16 +451,34 @@ |
455 | 451 | !(tx->flags & IEEE80211_TXRXD_TX_INJECTED)) { |
456 | 452 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); |
457 | 453 | return TXRX_DROP; |
458 | - } else { | |
454 | + } else | |
459 | 455 | tx->key = NULL; |
460 | - tx->u.tx.control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | |
461 | - } | |
462 | 456 | |
463 | 457 | if (tx->key) { |
458 | + u16 ftype, stype; | |
459 | + | |
464 | 460 | tx->key->tx_rx_count++; |
465 | 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 | 482 | return TXRX_CONTINUE; |
469 | 483 | } |
470 | 484 | |
... | ... | @@ -705,15 +719,6 @@ |
705 | 719 | } |
706 | 720 | } |
707 | 721 | } |
708 | - | |
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 | 722 | |
718 | 723 | return TXRX_CONTINUE; |
719 | 724 | } |
net/mac80211/wep.c
... | ... | @@ -349,16 +349,6 @@ |
349 | 349 | ieee80211_txrx_result |
350 | 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 | 352 | tx->u.tx.control->iv_len = WEP_IV_LEN; |
363 | 353 | tx->u.tx.control->icv_len = WEP_ICV_LEN; |
364 | 354 | ieee80211_tx_set_iswep(tx); |
net/mac80211/wpa.c
... | ... | @@ -245,16 +245,9 @@ |
245 | 245 | ieee80211_txrx_result |
246 | 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 | 248 | struct sk_buff *skb = tx->skb; |
251 | 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 | 251 | tx->u.tx.control->icv_len = TKIP_ICV_LEN; |
259 | 252 | tx->u.tx.control->iv_len = TKIP_IV_LEN; |
260 | 253 | ieee80211_tx_set_iswep(tx); |
261 | 254 | |
... | ... | @@ -501,15 +494,8 @@ |
501 | 494 | ieee80211_txrx_result |
502 | 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 | 497 | struct sk_buff *skb = tx->skb; |
507 | 498 | int test = 0; |
508 | - | |
509 | - fc = le16_to_cpu(hdr->frame_control); | |
510 | - | |
511 | - if (!WLAN_FC_DATA_PRESENT(fc)) | |
512 | - return TXRX_CONTINUE; | |
513 | 499 | |
514 | 500 | tx->u.tx.control->icv_len = CCMP_MIC_LEN; |
515 | 501 | tx->u.tx.control->iv_len = CCMP_HDR_LEN; |