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

Commit 077a9154 authored by Arik Nemtsov's avatar Arik Nemtsov Committed by John W. Linville
Browse files

mac80211: support adding IV-room in the skb for CCMP keys



Some cards can generate CCMP IVs in HW, but require the space for the IV
to be pre-allocated in the frame at the correct offset. Add a key flag
that allows us to achieve this.

Signed-off-by: default avatarArik Nemtsov <arik@wizery.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 3b7b72ee
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -901,6 +901,10 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
 * @IEEE80211_KEY_FLAG_SW_MGMT: This flag should be set by the driver for a
 *	CCMP key if it requires CCMP encryption of management frames (MFP) to
 *	be done in software.
 * @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver
 *	for a CCMP key if space should be prepared for the IV, but the IV
 *	itself should not be generated. Do not set together with
 *	@IEEE80211_KEY_FLAG_GENERATE_IV on the same key.
 */
enum ieee80211_key_flags {
	IEEE80211_KEY_FLAG_WMM_STA	= 1<<0,
@@ -908,6 +912,7 @@ enum ieee80211_key_flags {
	IEEE80211_KEY_FLAG_GENERATE_MMIC= 1<<2,
	IEEE80211_KEY_FLAG_PAIRWISE	= 1<<3,
	IEEE80211_KEY_FLAG_SW_MGMT	= 1<<4,
	IEEE80211_KEY_FLAG_PUT_IV_SPACE = 1<<5,
};

/**
+7 −2
Original line number Diff line number Diff line
@@ -133,9 +133,13 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
		key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;

		if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
		      (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
		      (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
		      (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
			sdata->crypto_tx_tailroom_needed_cnt--;

		WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
			(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV));

		return 0;
	}

@@ -178,7 +182,8 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
	sdata = key->sdata;

	if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
	      (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
	      (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
	      (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
		increment_tailroom_need_count(sdata);

	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+7 −1
Original line number Diff line number Diff line
@@ -390,7 +390,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
	u8 scratch[6 * AES_BLOCK_SIZE];

	if (info->control.hw_key &&
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
		/*
		 * hwaccel has no need for preallocated room for CCMP
		 * header or MIC fields
@@ -412,6 +413,11 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)

	pos = skb_push(skb, CCMP_HDR_LEN);
	memmove(pos, pos + CCMP_HDR_LEN, hdrlen);

	/* the HW only needs room for the IV, but not the actual IV */
	if (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)
		return 0;

	hdr = (struct ieee80211_hdr *) pos;
	pos += hdrlen;