Просмотр исходного кода

qcacmn: [CRYPTO] Refactor converged crypto to support BE/LE hosts

Refactor crypto module's definition of frame header to allow byte access
to 16-bit fields like frame_ctrl, seq_ctrl, duration id. This saves us
from doing endianness specific conversions during encap/decap in
the datapath.

Change-Id: Ie21c47d7e5b159b4db7e7704f091fe107fb663d1
CRs-Fixed: 2233228
Padma Raghunathan 7 лет назад
Родитель
Сommit
9492161c23

+ 10 - 0
umac/cmn_services/crypto/inc/wlan_crypto_global_api.h

@@ -535,4 +535,14 @@ uint8_t wlan_crypto_get_peer_fils_aead(struct wlan_objmgr_peer *peer);
  */
 void wlan_crypto_set_peer_fils_aead(
 			struct wlan_objmgr_peer *peer, uint8_t value);
+/**
+ * wlan_crypto_get_keyid - get keyid from frame
+ * @data: frame
+ * @hdrlen: 802.11 header length
+ *
+ * This function parse frame and returns keyid
+ *
+ * Return: keyid
+ */
+uint16_t wlan_crypto_get_keyid(uint8_t *data, int hdrlen);
 #endif /* end of _WLAN_CRYPTO_GLOBAL_API_H_ */

+ 28 - 28
umac/cmn_services/crypto/src/wlan_crypto_aes_i.h

@@ -154,43 +154,43 @@ static inline uint32_t rotr(uint32_t val, int bits)
 #define WLAN_ALEN               (6)
 
 struct ieee80211_hdr {
-	uint16_t frame_control;
-	uint16_t duration_id;
-	uint8_t  addr1[WLAN_ALEN];
-	uint8_t  addr2[WLAN_ALEN];
-	uint8_t  addr3[WLAN_ALEN];
-	uint16_t seq_ctrl;
+	uint8_t frame_control[2];
+	uint8_t duration_id[2];
+	uint8_t addr1[WLAN_ALEN];
+	uint8_t addr2[WLAN_ALEN];
+	uint8_t addr3[WLAN_ALEN];
+	uint8_t seq_ctrl[2];
 } __packed;
 
 struct ieee80211_hdr_addr4 {
-	uint16_t frame_control;
-	uint16_t duration_id;
-	uint8_t  addr1[WLAN_ALEN];
-	uint8_t  addr2[WLAN_ALEN];
-	uint8_t  addr3[WLAN_ALEN];
-	uint16_t seq_ctrl;
-	uint8_t  addr4[WLAN_ALEN];
+	uint8_t frame_control[2];
+	uint8_t duration_id[2];
+	uint8_t addr1[WLAN_ALEN];
+	uint8_t addr2[WLAN_ALEN];
+	uint8_t addr3[WLAN_ALEN];
+	uint8_t seq_ctrl[2];
+	uint8_t addr4[WLAN_ALEN];
 } __packed;
 
 struct ieee80211_hdr_qos {
-	uint16_t frame_control;
-	uint16_t duration_id;
-	uint8_t  addr1[WLAN_ALEN];
-	uint8_t  addr2[WLAN_ALEN];
-	uint8_t  addr3[WLAN_ALEN];
-	uint16_t seq_ctrl;
-	uint16_t qos;
+	uint8_t frame_control[2];
+	uint8_t duration_id[2];
+	uint8_t addr1[WLAN_ALEN];
+	uint8_t addr2[WLAN_ALEN];
+	uint8_t addr3[WLAN_ALEN];
+	uint8_t seq_ctrl[2];
+	uint8_t qos[2];
 } __packed;
 
 struct ieee80211_hdr_qos_addr4 {
-	uint16_t frame_control;
-	uint16_t duration_id;
-	uint8_t  addr1[WLAN_ALEN];
-	uint8_t  addr2[WLAN_ALEN];
-	uint8_t  addr3[WLAN_ALEN];
-	uint16_t seq_ctrl;
-	uint8_t  addr4[WLAN_ALEN];
-	uint16_t qos;
+	uint8_t frame_control[2];
+	uint8_t duration_id[2];
+	uint8_t addr1[WLAN_ALEN];
+	uint8_t addr2[WLAN_ALEN];
+	uint8_t addr3[WLAN_ALEN];
+	uint8_t seq_ctrl[2];
+	uint8_t addr4[WLAN_ALEN];
+	uint8_t qos[2];
 } __packed;
 
 int wlan_crypto_rijndaelKeySetupEnc(uint32_t rk[], const uint8_t cipherKey[],

+ 16 - 15
umac/cmn_services/crypto/src/wlan_crypto_ccmp_sw.c

@@ -18,39 +18,40 @@
 static void ccmp_aad_nonce(const struct ieee80211_hdr *hdr, const uint8_t *data,
 			   uint8_t *aad, size_t *aad_len, uint8_t *nonce)
 {
-	uint16_t fc, stype, seq;
+	uint16_t seq;
+	uint8_t stype;
 	int qos = 0, addr4 = 0;
 	uint8_t *pos;
 
 	nonce[0] = 0;
 
-	fc = qdf_le16_to_cpu(hdr->frame_control);
-	stype = WLAN_FC_GET_STYPE(fc);
-	if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
-	    (WLAN_FC_TODS | WLAN_FC_FROMDS))
+	stype = WLAN_FC0_GET_STYPE(hdr->frame_control[0]);
+	if ((hdr->frame_control[1] & WLAN_FC1_DIR_MASK) ==
+	    (WLAN_FC1_DSTODS))
 		addr4 = 1;
 
-	if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) {
-		fc &= ~0x0070; /* Mask subtype bits */
+	if (WLAN_FC0_GET_TYPE(hdr->frame_control[0]) == WLAN_FC0_TYPE_DATA) {
+		aad[0] &= ~0x70; /* Mask subtype bits */
 		if (stype & 0x08) {
 			const uint8_t *qc;
 			qos = 1;
-			fc &= ~WLAN_FC_ORDER;
+			aad[1] &= ~WLAN_FC1_ORDER;
 			qc = (const uint8_t *) (hdr + 1);
 			if (addr4)
 				qc += WLAN_ALEN;
 			nonce[0] = qc[0] & 0x0f;
 		}
-	} else if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT)
+	} else if (WLAN_FC0_GET_TYPE(hdr->frame_control[0])
+						== WLAN_FC0_TYPE_MGMT) {
 		nonce[0] |= 0x10; /* Management */
+	}
 
-	fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA);
-	fc |= WLAN_FC_ISWEP;
-	wlan_crypto_put_le16(aad, fc);
+	aad[1] &= ~(WLAN_FC1_RETRY | WLAN_FC1_PWRMGT | WLAN_FC1_MOREDATA);
+	aad[1] |= WLAN_FC1_ISWEP;
 	pos = aad + 2;
 	qdf_mem_copy(pos, hdr->addr1, 3 * WLAN_ALEN);
 	pos += 3 * WLAN_ALEN;
-	seq = qdf_le16_to_cpu(hdr->seq_ctrl);
+	seq = qdf_le16_to_cpu(*((uint16_t *)&hdr->seq_ctrl[0]));
 	seq &= ~0xfff0; /* Mask Seq#; do not modify Frag# */
 	wlan_crypto_put_le16(pos, seq);
 	pos += 2;
@@ -157,7 +158,7 @@ uint8_t *wlan_crypto_ccmp_encrypt(const uint8_t *tk, uint8_t *frame,
 	qdf_mem_copy(crypt, frame, hdrlen + CCMP_IV_SIZE);
 
 	hdr = (struct ieee80211_hdr *) crypt;
-	hdr->frame_control |= qdf_cpu_to_le16(WLAN_FC_ISWEP);
+	hdr->frame_control[1] |= WLAN_FC1_ISWEP;
 	pos = crypt + hdrlen + 8;
 
 	qdf_mem_set(aad, sizeof(aad), 0);
@@ -250,7 +251,7 @@ uint8_t *wlan_crypto_ccmp_256_encrypt(const uint8_t *tk, uint8_t *frame,
 
 	qdf_mem_copy(crypt, frame, hdrlen);
 	hdr = (struct ieee80211_hdr *) crypt;
-	hdr->frame_control |= qdf_cpu_to_le16(WLAN_FC_ISWEP);
+	hdr->frame_control[1] |= WLAN_FC1_ISWEP;
 	pos = crypt + hdrlen;
 	*pos++ = pn[5]; /* PN0 */
 	*pos++ = pn[4]; /* PN1 */

+ 63 - 82
umac/cmn_services/crypto/src/wlan_crypto_def_i.h

@@ -25,68 +25,70 @@
 #include "wlan_crypto_aes_i.h"
 
 /* IEEE 802.11 defines */
-#define WLAN_FC_PVER      0x0003
-#define WLAN_FC_TODS      0x0100
-#define WLAN_FC_FROMDS    0x0200
-#define WLAN_FC_MOREFRAG  0x0400
-#define WLAN_FC_RETRY     0x0800
-#define WLAN_FC_PWRMGT    0x1000
-#define WLAN_FC_MOREDATA  0x2000
-#define WLAN_FC_ISWEP     0x4000
-#define WLAN_FC_ORDER     0x8000
-
-#define WLAN_FC_GET_TYPE(fc)    (((fc) & 0x000c) >> 2)
-#define WLAN_FC_GET_STYPE(fc)   (((fc) & 0x00f0) >> 4)
+#define WLAN_FC0_PVER      0x0003
+#define WLAN_FC1_DIR_MASK  0x03
+#define WLAN_FC1_TODS      0x01
+#define WLAN_FC1_FROMDS    0x02
+#define WLAN_FC1_DSTODS    0x03
+#define WLAN_FC1_MOREFRAG  0x04
+#define WLAN_FC1_RETRY     0x08
+#define WLAN_FC1_PWRMGT    0x10
+#define WLAN_FC1_MOREDATA  0x20
+#define WLAN_FC1_ISWEP     0x40
+#define WLAN_FC1_ORDER     0x80
+
+#define WLAN_FC0_GET_TYPE(fc)    (((fc) & 0x0c) >> 2)
+#define WLAN_FC0_GET_STYPE(fc)   (((fc) & 0xf0) >> 4)
 
 #define WLAN_INVALID_MGMT_SEQ   0xffff
 #define WLAN_SEQ_MASK           0x0fff
-#define WLAN_QOS_TID_MASK       0x00ff
+#define WLAN_QOS_TID_MASK       0x0f
 #define WLAN_GET_SEQ_FRAG(seq) ((seq) & (BIT(3) | BIT(2) | BIT(1) | BIT(0)))
 #define WLAN_GET_SEQ_SEQ(seq) \
 	(((seq) & (~(BIT(3) | BIT(2) | BIT(1) | BIT(0)))) >> 4)
 
-#define WLAN_FC_TYPE_MGMT        0
-#define WLAN_FC_TYPE_CTRL        1
-#define WLAN_FC_TYPE_DATA        2
+#define WLAN_FC0_TYPE_MGMT        0
+#define WLAN_FC0_TYPE_CTRL        1
+#define WLAN_FC0_TYPE_DATA        2
 
 /* management */
-#define WLAN_FC_STYPE_ASSOC_REQ      0
-#define WLAN_FC_STYPE_ASSOC_RESP     1
-#define WLAN_FC_STYPE_REASSOC_REQ    2
-#define WLAN_FC_STYPE_REASSOC_RESP   3
-#define WLAN_FC_STYPE_PROBE_REQ      4
-#define WLAN_FC_STYPE_PROBE_RESP     5
-#define WLAN_FC_STYPE_BEACON         8
-#define WLAN_FC_STYPE_ATIM           9
-#define WLAN_FC_STYPE_DISASSOC      10
-#define WLAN_FC_STYPE_AUTH          11
-#define WLAN_FC_STYPE_DEAUTH        12
-#define WLAN_FC_STYPE_ACTION        13
+#define WLAN_FC0_STYPE_ASSOC_REQ      0
+#define WLAN_FC0_STYPE_ASSOC_RESP     1
+#define WLAN_FC0_STYPE_REASSOC_REQ    2
+#define WLAN_FC0_STYPE_REASSOC_RESP   3
+#define WLAN_FC0_STYPE_PROBE_REQ      4
+#define WLAN_FC0_STYPE_PROBE_RESP     5
+#define WLAN_FC0_STYPE_BEACON         8
+#define WLAN_FC0_STYPE_ATIM           9
+#define WLAN_FC0_STYPE_DISASSOC      10
+#define WLAN_FC0_STYPE_AUTH          11
+#define WLAN_FC0_STYPE_DEAUTH        12
+#define WLAN_FC0_STYPE_ACTION        13
 
 /* control */
-#define WLAN_FC_STYPE_PSPOLL        10
-#define WLAN_FC_STYPE_RTS           11
-#define WLAN_FC_STYPE_CTS           12
-#define WLAN_FC_STYPE_ACK           13
-#define WLAN_FC_STYPE_CFEND         14
-#define WLAN_FC_STYPE_CFENDACK      15
+#define WLAN_FC0_STYPE_PSPOLL        10
+#define WLAN_FC0_STYPE_RTS           11
+#define WLAN_FC0_STYPE_CTS           12
+#define WLAN_FC0_STYPE_ACK           13
+#define WLAN_FC0_STYPE_CFEND         14
+#define WLAN_FC0_STYPE_CFENDACK      15
 
 /* data */
-#define WLAN_FC_STYPE_DATA                0
-#define WLAN_FC_STYPE_DATA_CFACK          1
-#define WLAN_FC_STYPE_DATA_CFPOLL         2
-#define WLAN_FC_STYPE_DATA_CFACKPOLL      3
-#define WLAN_FC_STYPE_NULLFUNC            4
-#define WLAN_FC_STYPE_CFACK               5
-#define WLAN_FC_STYPE_CFPOLL              6
-#define WLAN_FC_STYPE_CFACKPOLL           7
-#define WLAN_FC_STYPE_QOS_DATA            8
-#define WLAN_FC_STYPE_QOS_DATA_CFACK      9
-#define WLAN_FC_STYPE_QOS_DATA_CFPOLL    10
-#define WLAN_FC_STYPE_QOS_DATA_CFACKPOLL 11
-#define WLAN_FC_STYPE_QOS_NULL           12
-#define WLAN_FC_STYPE_QOS_CFPOLL         14
-#define WLAN_FC_STYPE_QOS_CFACKPOLL      15
+#define WLAN_FC0_STYPE_DATA                0
+#define WLAN_FC0_STYPE_DATA_CFACK          1
+#define WLAN_FC0_STYPE_DATA_CFPOLL         2
+#define WLAN_FC0_STYPE_DATA_CFACKPOLL      3
+#define WLAN_FC0_STYPE_NULLFUNC            4
+#define WLAN_FC0_STYPE_CFACK               5
+#define WLAN_FC0_STYPE_CFPOLL              6
+#define WLAN_FC0_STYPE_CFACKPOLL           7
+#define WLAN_FC0_STYPE_QOS_DATA            8
+#define WLAN_FC0_STYPE_QOS_DATA_CFACK      9
+#define WLAN_FC0_STYPE_QOS_DATA_CFPOLL    10
+#define WLAN_FC0_STYPE_QOS_DATA_CFACKPOLL 11
+#define WLAN_FC0_STYPE_QOS_NULL           12
+#define WLAN_FC0_STYPE_QOS_CFPOLL         14
+#define WLAN_FC0_STYPE_QOS_CFACKPOLL      15
 
 #define WLAN_TID_SIZE                    17
 #define WLAN_NONQOS_SEQ                  16
@@ -466,8 +468,7 @@ struct wlan_crypto_cipher {
 static inline bool wlan_crypto_is_data_protected(const void *data)
 {
 	const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)data;
-
-	if (hdr->frame_control & WLAN_FC_ISWEP)
+	if (hdr->frame_control[1] & WLAN_FC1_ISWEP)
 		return true;
 	else
 		return false;
@@ -486,41 +487,21 @@ static inline int ieee80211_hdrsize(const void *data)
 	const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)data;
 	int16_t size = sizeof(struct ieee80211_hdr);
 
-	if ((hdr->frame_control & (WLAN_FC_TODS | WLAN_FC_FROMDS))
-				== (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
+	if ((hdr->frame_control[1] & WLAN_FC1_DIR_MASK)
+				== (WLAN_FC1_DSTODS)) {
 		size += WLAN_ALEN;
 	}
 
-	if (((WLAN_FC_GET_STYPE(hdr->frame_control)
-			== WLAN_FC_STYPE_QOS_DATA))) {
+	if (((WLAN_FC0_GET_STYPE(hdr->frame_control[0])
+			== WLAN_FC0_STYPE_QOS_DATA))) {
 		size += sizeof(uint16_t);
 		/* Qos frame with Order bit set indicates an HTC frame */
-		if (hdr->frame_control & WLAN_FC_ORDER)
+		if (hdr->frame_control[1] & WLAN_FC1_ORDER)
 			size += (sizeof(uint8_t)*4);
 	}
 	return size;
 }
 
-/**
- * wlan_crypto_get_keyid - get keyid from frame
- * @data: frame
- *
- * This function parse frame and returns keyid
- *
- * Return: keyid
- */
-static inline uint16_t wlan_crypto_get_keyid(uint8_t *data)
-{
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)data;
-
-	if (hdr->frame_control & WLAN_FC_ISWEP) {
-		uint8_t *iv;
-		iv = data + ieee80211_hdrsize(data);
-		return ((iv[3] >> 6) & 0x3);
-	} else
-		return WLAN_CRYPTO_KEYIX_NONE;
-}
-
 /**
  * wlan_get_tid - get tid of the frame
  * @data: frame
@@ -533,14 +514,14 @@ static inline int wlan_get_tid(const void *data)
 {
 	const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)data;
 
-	if (((WLAN_FC_GET_STYPE(hdr->frame_control)
-				== WLAN_FC_STYPE_QOS_DATA))) {
-		if ((hdr->frame_control & (WLAN_FC_TODS | WLAN_FC_FROMDS))
-				== (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
-			return ((struct ieee80211_hdr_qos_addr4 *)data)->qos
+	if (((WLAN_FC0_GET_STYPE(hdr->frame_control[0])
+				== WLAN_FC0_STYPE_QOS_DATA))) {
+		if ((hdr->frame_control[1] & WLAN_FC1_DIR_MASK)
+					== (WLAN_FC1_DSTODS)) {
+			return ((struct ieee80211_hdr_qos_addr4 *)data)->qos[0]
 							& WLAN_QOS_TID_MASK;
 		} else {
-			return ((struct ieee80211_hdr_qos *)data)->qos
+			return ((struct ieee80211_hdr_qos *)data)->qos[0]
 							& WLAN_QOS_TID_MASK;
 		}
 	} else

+ 10 - 10
umac/cmn_services/crypto/src/wlan_crypto_fils.c

@@ -63,14 +63,14 @@ fils_parse_ie(qdf_nbuf_t wbuf, uint8_t hdrlen, uint8_t **cap_info,
 	struct ieee80211_hdr *hdr;
 	uint32_t pktlen_left = 0;
 	bool fils_found = 0;
-	uint16_t subtype = 0;
+	uint8_t subtype = 0;
 	uint8_t *frm = NULL;
 	uint8_t elem_id;
 	uint32_t len;
 
 	frm = (uint8_t *)qdf_nbuf_data(wbuf);
 	hdr = (struct ieee80211_hdr *)frm;
-	subtype = WLAN_FC_GET_STYPE(hdr->frame_control);
+	subtype = WLAN_FC0_GET_STYPE(hdr->frame_control[0]);
 
 	pktlen_left = qdf_nbuf_len(wbuf);
 
@@ -86,8 +86,8 @@ fils_parse_ie(qdf_nbuf_t wbuf, uint8_t hdrlen, uint8_t **cap_info,
 	/* pointer to the capability information field */
 	*cap_info = (uint8_t *)frm;
 
-	if (subtype == WLAN_FC_STYPE_ASSOC_RESP ||
-	    subtype == WLAN_FC_STYPE_REASSOC_RESP) {
+	if (subtype == WLAN_FC0_STYPE_ASSOC_RESP ||
+	    subtype == WLAN_FC0_STYPE_REASSOC_RESP) {
 		/* assoc resp frame - capability (2), status (2), associd (2) */
 		if (pktlen_left < ASSOC_RESP_FIXED_FIELDS_LEN) {
 			qdf_print(
@@ -98,7 +98,7 @@ fils_parse_ie(qdf_nbuf_t wbuf, uint8_t hdrlen, uint8_t **cap_info,
 
 		frm += ASSOC_RESP_FIXED_FIELDS_LEN;
 		pktlen_left -= ASSOC_RESP_FIXED_FIELDS_LEN;
-	} else if (subtype == WLAN_FC_STYPE_ASSOC_REQ) {
+	} else if (subtype == WLAN_FC0_STYPE_ASSOC_REQ) {
 		/* assoc req frame - capability(2), listen interval (2) */
 		if (pktlen_left < ASSOC_REQ_FIXED_FIELDS_LEN) {
 			qdf_print(
@@ -109,7 +109,7 @@ fils_parse_ie(qdf_nbuf_t wbuf, uint8_t hdrlen, uint8_t **cap_info,
 
 		frm += ASSOC_REQ_FIXED_FIELDS_LEN;
 		pktlen_left -= ASSOC_REQ_FIXED_FIELDS_LEN;
-	} else if (subtype == WLAN_FC_STYPE_REASSOC_REQ) {
+	} else if (subtype == WLAN_FC0_STYPE_REASSOC_REQ) {
 		/* assoc req frame - capability(2),
 		 * Listen interval(2),
 		 * Current AP address(6)
@@ -228,7 +228,7 @@ fils_aead_encap(struct wlan_crypto_key *key, qdf_nbuf_t wbuf,
 	struct wlan_crypto_fils_aad_key *fils_key = NULL;
 	uint8_t *buf = NULL;
 	uint32_t bufsize = 0;
-	uint16_t subtype = 0;
+	uint8_t subtype = 0;
 
 	if (!key) {
 		qdf_print(FL("Invalid Input\n"));
@@ -252,9 +252,9 @@ fils_aead_encap(struct wlan_crypto_key *key, qdf_nbuf_t wbuf,
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	subtype = WLAN_FC_GET_STYPE(hdr->frame_control);
-	if ((subtype != WLAN_FC_STYPE_ASSOC_RESP) &&
-	    (subtype != WLAN_FC_STYPE_REASSOC_RESP))
+	subtype = WLAN_FC0_GET_STYPE(hdr->frame_control[0]);
+	if ((subtype != WLAN_FC0_STYPE_ASSOC_RESP) &&
+	    (subtype != WLAN_FC0_STYPE_REASSOC_RESP))
 		return QDF_STATUS_E_FAILURE;
 
 	if (fils_parse_ie(wbuf, hdrlen, &cap_info, &fils_session, &ie_start)

+ 11 - 12
umac/cmn_services/crypto/src/wlan_crypto_gcmp_sw.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
  */
 /*
  * GCM with GMAC Protocol (GCMP)
@@ -18,34 +18,33 @@
 static void gcmp_aad_nonce(const struct ieee80211_hdr *hdr, const uint8_t *data,
 			   uint8_t *aad, size_t *aad_len, uint8_t *nonce)
 {
-	uint16_t fc, stype, seq;
+	uint16_t seq;
+	uint8_t stype;
 	int qos = 0, addr4 = 0;
 	uint8_t *pos;
 
-	fc = qdf_le16_to_cpu(hdr->frame_control);
-	stype = WLAN_FC_GET_STYPE(fc);
-	if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
-	    (WLAN_FC_TODS | WLAN_FC_FROMDS))
+	stype = WLAN_FC0_GET_STYPE(hdr->frame_control[0]);
+	if ((hdr->frame_control[1] & WLAN_FC1_DIR_MASK) ==
+	    (WLAN_FC1_DSTODS))
 		addr4 = 1;
 
-	if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) {
-		fc &= ~0x0070; /* Mask subtype bits */
+	if (WLAN_FC0_GET_TYPE(hdr->frame_control[0]) == WLAN_FC0_TYPE_DATA) {
+		aad[0] &= ~0x0070; /* Mask subtype bits */
 		if (stype & 0x08) {
 			const uint8_t *qc;
 			qos = 1;
-			fc &= ~WLAN_FC_ORDER;
+			aad[1] &= ~WLAN_FC1_ORDER;
 			qc = (const uint8_t *) (hdr + 1);
 			if (addr4)
 				qc += WLAN_ALEN;
 		}
 	}
 
-	fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA);
-	wlan_crypto_put_le16(aad, fc);
+	aad[1] &= ~(WLAN_FC1_RETRY | WLAN_FC1_PWRMGT | WLAN_FC1_MOREDATA);
 	pos = aad + 2;
 	qdf_mem_copy(pos, hdr->addr1, 3 * WLAN_ALEN);
 	pos += 3 * WLAN_ALEN;
-	seq = qdf_le16_to_cpu(hdr->seq_ctrl);
+	seq = qdf_le16_to_cpu(*((uint16_t *)&hdr->seq_ctrl[0]));
 	seq &= ~0xfff0; /* Mask Seq#; do not modify Frag# */
 	wlan_crypto_put_le16(pos, seq);
 	pos += 2;

+ 33 - 6
umac/cmn_services/crypto/src/wlan_crypto_global_api.c

@@ -1572,10 +1572,10 @@ uint8_t *wlan_crypto_add_mmie(struct wlan_objmgr_vdev *vdev,
 	/* generate BIP AAD: FC(masked) || A1 || A2 || A3 */
 
 	/* FC type/subtype */
-	aad[0] = hdr->frame_control & 0xff;
+	aad[0] = hdr->frame_control[0];
 	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
-	aad[1] = (hdr->frame_control & ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT
-						| WLAN_FC_MOREDATA)) >> 8;
+	aad[1] = (hdr->frame_control[1] & ~(WLAN_FC1_RETRY | WLAN_FC1_PWRMGT
+						| WLAN_FC1_MOREDATA));
 	/* A1 || A2 || A3 */
 	qdf_mem_copy(aad + 2, hdr->addr1, WLAN_ALEN);
 	qdf_mem_copy(aad + 8, hdr->addr2, WLAN_ALEN);
@@ -1705,10 +1705,10 @@ bool wlan_crypto_is_mmie_valid(struct wlan_objmgr_vdev *vdev,
 	/* generate BIP AAD: FC(masked) || A1 || A2 || A3 */
 
 	/* FC type/subtype */
-	aad[0] = hdr->frame_control & 0xff;
+	aad[0] = hdr->frame_control[0];
 	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
-	aad[1] = (hdr->frame_control & ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT
-						| WLAN_FC_MOREDATA)) >> 8;
+	aad[1] = (hdr->frame_control[1] & ~(WLAN_FC1_RETRY | WLAN_FC1_PWRMGT
+						| WLAN_FC1_MOREDATA));
 	/* A1 || A2 || A3 */
 	qdf_mem_copy(aad + 2, hdr->addr1, 3 * WLAN_ALEN);
 
@@ -3077,3 +3077,30 @@ wlan_crypto_set_peer_fils_aead(struct wlan_objmgr_peer *peer, uint8_t value)
 
 	crypto_priv->fils_aead_set = value;
 }
+
+/**
+ * wlan_crypto_get_keyid - get keyid from frame
+ * @data: frame
+ *
+ * This function parse frame and returns keyid
+ *
+ * Return: keyid
+ */
+uint16_t wlan_crypto_get_keyid(uint8_t *data, int hdrlen)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)data;
+	uint8_t *iv;
+
+	if (hdr->frame_control[1] & WLAN_FC1_ISWEP) {
+		iv = data + hdrlen;
+		/*
+		 * iv[3] is the Key ID octet in the CCMP/TKIP/WEP headers
+		 * Bits 6–7 of the Key ID octet are for the Key ID subfield
+		 */
+		return ((iv[3] >> 6) & 0x3);
+	} else {
+		return WLAN_CRYPTO_KEYIX_NONE;
+	}
+}
+
+qdf_export_symbol(wlan_crypto_get_keyid);

+ 9 - 13
umac/cmn_services/crypto/src/wlan_crypto_tkip_sw.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
  */
 /*
  * Temporal Key Integrity Protocol (CCMP)
@@ -246,18 +246,17 @@ static void michael_mic(const uint8_t *key, const uint8_t *hdr,
 static void michael_mic_hdr(const struct ieee80211_hdr *hdr11, uint8_t *hdr)
 {
 	int hdrlen = 24;
-	uint16_t fc = qdf_le16_to_cpu(hdr11->frame_control);
 
-	switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
-	case WLAN_FC_TODS:
+	switch (hdr11->frame_control[1] & (WLAN_FC1_FROMDS | WLAN_FC1_TODS)) {
+	case WLAN_FC1_TODS:
 		qdf_mem_copy(hdr, hdr11->addr3, WLAN_ALEN); /* DA */
 		qdf_mem_copy(hdr + WLAN_ALEN, hdr11->addr2, WLAN_ALEN); /* SA */
 		break;
-	case WLAN_FC_FROMDS:
+	case WLAN_FC1_FROMDS:
 		qdf_mem_copy(hdr, hdr11->addr1, WLAN_ALEN); /* DA */
 		qdf_mem_copy(hdr + WLAN_ALEN, hdr11->addr3, WLAN_ALEN); /* SA */
 		break;
-	case WLAN_FC_FROMDS | WLAN_FC_TODS:
+	case WLAN_FC1_FROMDS | WLAN_FC1_TODS:
 		qdf_mem_copy(hdr, hdr11->addr3, WLAN_ALEN); /* DA */
 		qdf_mem_copy(hdr + WLAN_ALEN, hdr11 + 1, WLAN_ALEN); /* SA */
 		hdrlen += WLAN_ALEN;
@@ -268,8 +267,8 @@ static void michael_mic_hdr(const struct ieee80211_hdr *hdr11, uint8_t *hdr)
 		break;
 	}
 
-	if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
-	    (WLAN_FC_GET_STYPE(fc) & 0x08)) {
+	if (WLAN_FC0_GET_TYPE(hdr11->frame_control[0]) == WLAN_FC0_TYPE_DATA &&
+	    (WLAN_FC0_GET_STYPE(hdr11->frame_control[0]) & 0x08)) {
 		const uint8_t *qos = ((const uint8_t *) hdr11) + hdrlen;
 		hdr[12] = qos[0] & 0x0f; /* priority */
 	} else
@@ -292,7 +291,6 @@ uint8_t *wlan_crypto_tkip_decrypt(const uint8_t *tk,
 	const uint8_t *mic_key;
 	uint8_t michael_hdr[16];
 	uint8_t mic[8];
-	uint16_t fc = qdf_le16_to_cpu(hdr->frame_control);
 
 	if (data_len < 8 + 4)
 		return NULL;
@@ -333,7 +331,7 @@ uint8_t *wlan_crypto_tkip_decrypt(const uint8_t *tk,
 	}
 
 	michael_mic_hdr(hdr, michael_hdr);
-	mic_key = tk + ((fc & WLAN_FC_FROMDS) ? 16 : 24);
+	mic_key = tk + ((hdr->frame_control[1] & WLAN_FC1_FROMDS) ? 16 : 24);
 	michael_mic(mic_key, michael_hdr, plain, plain_len - 8, mic);
 	if (qdf_mem_cmp(mic, plain + plain_len - 8, 8) != 0) {
 		wpa_printf(MSG_INFO, "TKIP: Michael MIC mismatch in a frame "
@@ -364,7 +362,6 @@ uint8_t *wlan_crypto_tkip_encrypt(const uint8_t *tk, uint8_t *frame,
 	uint8_t michael_hdr[16];
 	uint8_t mic[8];
 	struct ieee80211_hdr *hdr;
-	uint16_t fc;
 	const uint8_t *mic_key;
 	uint8_t *pos;
 	uint16_t iv16;
@@ -375,10 +372,9 @@ uint8_t *wlan_crypto_tkip_encrypt(const uint8_t *tk, uint8_t *frame,
 	if (len < sizeof(*hdr) || len < hdrlen)
 		return NULL;
 	hdr = (struct ieee80211_hdr *) frame;
-	fc = qdf_le16_to_cpu(hdr->frame_control);
 
 	michael_mic_hdr(hdr, michael_hdr);
-	mic_key = tk + ((fc & WLAN_FC_FROMDS) ? 16 : 24);
+	mic_key = tk + ((hdr->frame_control[1] & WLAN_FC1_FROMDS) ? 16 : 24);
 	michael_mic(mic_key, michael_hdr, frame + hdrlen, len - hdrlen, mic);
 	wpa_hexdump(MSG_EXCESSIVE, "TKIP: MIC", mic, sizeof(mic));
 	pos = frame + hdrlen;