Commit 176e4f84423af3105894a7d71b23c1a16678a6be

Authored by Johannes Berg
Committed by David S. Miller
1 parent 7bbdd2d987

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

... ... @@ -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 }
... ... @@ -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);
... ... @@ -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;