net/mac80211/wpa.c

Source file repositories/reference/linux-study-clean/net/mac80211/wpa.c

File Facts

System
Linux kernel
Corpus path
net/mac80211/wpa.c
Extension
.c
Size
28491 bytes
Lines
1076
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

ieee80211_is_mgmt(hdr->frame_control))) {
		/*
		 * hwaccel has no need for preallocated room for CCMP
		 * header or MIC fields
		 */
		return 0;
	}

	hdrlen = ieee80211_hdrlen(hdr->frame_control);
	len = skb->len - hdrlen;

	if (info->control.hw_key)
		tail = 0;
	else
		tail = mic_len;

	if (WARN_ON(skb_tailroom(skb) < tail ||
		    skb_headroom(skb) < IEEE80211_CCMP_HDR_LEN))
		return -1;

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

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

	pos += hdrlen;

	pn64 = atomic64_inc_return(&key->conf.tx_pn);

	pn[5] = pn64;
	pn[4] = pn64 >> 8;
	pn[3] = pn64 >> 16;
	pn[2] = pn64 >> 24;
	pn[1] = pn64 >> 32;
	pn[0] = pn64 >> 40;

	ccmp_pn2hdr(pos, pn, key->conf.keyidx);

	/* hwaccel - with software CCMP header */
	if (info->control.hw_key)
		return 0;

	pos += IEEE80211_CCMP_HDR_LEN;
	ccmp_special_blocks(skb, pn, b_0, aad,
			    key->conf.flags & IEEE80211_KEY_FLAG_SPP_AMSDU,
			    false);
	return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
					 skb_put(skb, mic_len));
}


ieee80211_tx_result
ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx,
			      unsigned int mic_len)
{
	struct sk_buff *skb;

	ieee80211_tx_set_protected(tx);

	skb_queue_walk(&tx->skbs, skb) {
		if (ccmp_encrypt_skb(tx, skb, mic_len) < 0)
			return TX_DROP;
	}

	return TX_CONTINUE;
}


ieee80211_rx_result
ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
			      unsigned int mic_len)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
	int hdrlen;
	struct ieee80211_key *key = rx->key;
	struct sk_buff *skb = rx->skb;
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
	u8 pn[IEEE80211_CCMP_PN_LEN];
	int data_len;
	int queue;

	hdrlen = ieee80211_hdrlen(hdr->frame_control);

	if (!ieee80211_is_data(hdr->frame_control) &&
	    !ieee80211_is_robust_mgmt_frame(skb) &&
	    !ieee80211_require_encrypted_assoc(hdr->frame_control, rx->sta))
		return RX_CONTINUE;

Annotation

Implementation Notes