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
Dieser Commit ist enthalten in:
Padma Raghunathan
2018-04-30 10:02:09 +05:30
committet von nshrivas
Ursprung a5a30867c4
Commit 9492161c23
8 geänderte Dateien mit 179 neuen und 165 gelöschten Zeilen

Datei anzeigen

@@ -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_ */

Datei anzeigen

@@ -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[],

Datei anzeigen

@@ -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 */

Datei anzeigen

@@ -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_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_FC_GET_TYPE(fc) (((fc) & 0x000c) >> 2)
#define WLAN_FC_GET_STYPE(fc) (((fc) & 0x00f0) >> 4)
#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

Datei anzeigen

@@ -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)

Datei anzeigen

@@ -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;

Datei anzeigen

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

Datei anzeigen

@@ -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;