Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 176e4f84 authored by Johannes Berg's avatar Johannes Berg Committed by David S. Miller
Browse files

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: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7bbdd2d9
Loading
Loading
Loading
Loading
+22 −17
Original line number Diff line number Diff line
@@ -438,11 +438,7 @@ static ieee80211_txrx_result
ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx)
{
	struct ieee80211_key *key;
	const struct ieee80211_hdr *hdr;
	u16 fc;

	hdr = (const struct ieee80211_hdr *) tx->skb->data;
	fc = le16_to_cpu(hdr->frame_control);
	u16 fc = tx->fc;

	if (unlikely(tx->u.tx.control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT))
		tx->key = NULL;
@@ -455,16 +451,34 @@ ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx)
		 !(tx->flags & IEEE80211_TXRXD_TX_INJECTED)) {
		I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
		return TXRX_DROP;
	} else {
	} else
		tx->key = NULL;
		tx->u.tx.control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
	}

	if (tx->key) {
		u16 ftype, stype;

		tx->key->tx_rx_count++;
		/* TODO: add threshold stuff again */

		switch (tx->key->conf.alg) {
		case ALG_WEP:
			ftype = fc & IEEE80211_FCTL_FTYPE;
			stype = fc & IEEE80211_FCTL_STYPE;

			if (ftype == IEEE80211_FTYPE_MGMT &&
			    stype == IEEE80211_STYPE_AUTH)
				break;
		case ALG_TKIP:
		case ALG_CCMP:
			if (!WLAN_FC_DATA_PRESENT(fc))
				tx->key = NULL;
			break;
		}
	}

	if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
		tx->u.tx.control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;

	return TXRX_CONTINUE;
}

@@ -706,15 +720,6 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx)
		}
	}

	/*
	 * Tell hardware to not encrypt when we had sw crypto.
	 * Because we use the same flag to internally indicate that
	 * no (software) encryption should be done, we have to set it
	 * after all crypto handlers.
	 */
	if (tx->key && !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
		tx->u.tx.control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;

	return TXRX_CONTINUE;
}

+0 −10
Original line number Diff line number Diff line
@@ -349,16 +349,6 @@ static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb)
ieee80211_txrx_result
ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
	u16 fc;

	fc = le16_to_cpu(hdr->frame_control);

	if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
	     ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
	      (fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)))
		return TXRX_CONTINUE;

	tx->u.tx.control->iv_len = WEP_IV_LEN;
	tx->u.tx.control->icv_len = WEP_ICV_LEN;
	ieee80211_tx_set_iswep(tx);
+0 −14
Original line number Diff line number Diff line
@@ -245,16 +245,9 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx,
ieee80211_txrx_result
ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
	u16 fc;
	struct sk_buff *skb = tx->skb;
	int wpa_test = 0, test = 0;

	fc = le16_to_cpu(hdr->frame_control);

	if (!WLAN_FC_DATA_PRESENT(fc))
		return TXRX_CONTINUE;

	tx->u.tx.control->icv_len = TKIP_ICV_LEN;
	tx->u.tx.control->iv_len = TKIP_IV_LEN;
	ieee80211_tx_set_iswep(tx);
@@ -501,16 +494,9 @@ static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx,
ieee80211_txrx_result
ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
	u16 fc;
	struct sk_buff *skb = tx->skb;
	int test = 0;

	fc = le16_to_cpu(hdr->frame_control);

	if (!WLAN_FC_DATA_PRESENT(fc))
		return TXRX_CONTINUE;

	tx->u.tx.control->icv_len = CCMP_MIC_LEN;
	tx->u.tx.control->iv_len = CCMP_HDR_LEN;
	ieee80211_tx_set_iswep(tx);