feat(wifi) : Add FT with SAE feature

This commit is contained in:
tarun.kumar
2025-06-09 12:12:56 +05:30
parent 9ef6d3eac4
commit 324337369d
8 changed files with 273 additions and 57 deletions

View File

@@ -153,7 +153,7 @@ static void register_mgmt_frames(struct wpa_supplicant *wpa_s)
static int handle_auth_frame(u8 *frame, size_t len,
u8 *sender, int8_t rssi, u8 channel)
{
if (gWpaSm.key_mgmt == WPA_KEY_MGMT_FT_PSK) {
if (gWpaSm.key_mgmt == WPA_KEY_MGMT_FT_PSK || gWpaSm.key_mgmt == WPA_KEY_MGMT_FT_SAE) {
if (gWpaSm.ft_protocol) {
if (wpa_ft_process_response(&gWpaSm, frame + 6,
len - 6, 0, sender, NULL, 0) < 0) {
@@ -168,7 +168,7 @@ static int handle_auth_frame(u8 *frame, size_t len,
static int handle_assoc_frame(u8 *frame, size_t len,
u8 *sender, int8_t rssi, u8 channel)
{
if (gWpaSm.key_mgmt == WPA_KEY_MGMT_FT_PSK) {
if (gWpaSm.key_mgmt == WPA_KEY_MGMT_FT_PSK || gWpaSm.key_mgmt == WPA_KEY_MGMT_FT_SAE) {
if (gWpaSm.ft_protocol) {
if (wpa_ft_validate_reassoc_resp(&gWpaSm, frame + 6, len - 6, sender)) {
wpa_sm_set_ft_params(&gWpaSm, NULL, 0);

View File

@@ -77,6 +77,7 @@ enum {
WPA3_AUTH_PSK_EXT_KEY = 0x10,
/* this enum is in C2 ROM, do not change before WPA3_AUTH_PSK_EXT_KEY */
WPA3_AUTH_DPP = 0x11,
WPA3_AUTH_FT_SAE = 0x12,
WPA2_AUTH_INVALID
};

View File

@@ -28,6 +28,7 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr,
const u8 *mdie, size_t mdie_len,
const u8 *ftie, size_t ftie_len,
const u8 *rsnie, size_t rsnie_len,
const u8 *rsnxe, size_t rsnxe_len,
const u8 *ric, size_t ric_len, u8 *mic)
{
u8 *buf, *pos;
@@ -39,7 +40,7 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr,
return -1;
}
buf_len = 2 * ETH_ALEN + 1 + mdie_len + ftie_len + rsnie_len + ric_len;
buf_len = 2 * ETH_ALEN + 1 + mdie_len + ftie_len + rsnie_len + ric_len + rsnxe_len;
buf = os_malloc(buf_len);
if (buf == NULL)
return -1;
@@ -51,38 +52,41 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr,
pos += ETH_ALEN;
*pos++ = transaction_seqnum;
if (rsnie) {
os_memcpy(pos, rsnie, rsnie_len);
pos += rsnie_len;
os_memcpy(pos, rsnie, rsnie_len);
pos += rsnie_len;
}
if (mdie) {
os_memcpy(pos, mdie, mdie_len);
pos += mdie_len;
os_memcpy(pos, mdie, mdie_len);
pos += mdie_len;
}
if (ftie) {
struct rsn_ftie *_ftie;
os_memcpy(pos, ftie, ftie_len);
if (ftie_len < 2 + sizeof(*_ftie)) {
os_free(buf);
return -1;
}
_ftie = (struct rsn_ftie *) (pos + 2);
os_memset(_ftie->mic, 0, sizeof(_ftie->mic));
pos += ftie_len;
}
if (ric) {
os_memcpy(pos, ric, ric_len);
pos += ric_len;
}
struct rsn_ftie *_ftie;
os_memcpy(pos, ftie, ftie_len);
if (ftie_len < 2 + sizeof(*_ftie)) {
os_free(buf);
return -1;
}
_ftie = (struct rsn_ftie *) (pos + 2);
os_memset(_ftie->mic, 0, sizeof(_ftie->mic));
pos += ftie_len;
}
if (ric) {
os_memcpy(pos, ric, ric_len);
pos += ric_len;
}
if (rsnxe) {
os_memcpy(pos, rsnxe, rsnxe_len);
pos += rsnxe_len;
}
wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", buf, pos - buf);
if (omac1_aes_128(kck, buf, pos - buf, mic)) {
os_free(buf);
return -1;
}
if (omac1_aes_128(kck, buf, pos - buf, mic)) {
os_free(buf);
return -1;
}
os_free(buf);
return 0;
return 0;
}
@@ -151,6 +155,9 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
pos = ies;
end = ies + ies_len;
while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
u8 len;
len = pos[1];
switch (pos[0]) {
case WLAN_EID_RSN:
parse->rsn = pos + 2;
@@ -166,6 +173,13 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
if (data.num_pmkid == 1 && data.pmkid)
parse->rsn_pmkid = data.pmkid;
break;
case WLAN_EID_RSNX:
wpa_hexdump(MSG_DEBUG, "FT: RSNXE", pos, len);
if (len < 1)
break;
parse->rsnxe = pos + 2;
parse->rsnxe_len = pos[1];
break;
case WLAN_EID_MOBILITY_DOMAIN:
parse->mdie = pos + 2;
parse->mdie_len = pos[1];
@@ -198,16 +212,18 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
* Check that the protected IE count matches with IEs included in the
* frame.
*/
if (parse->rsnxe)
prot_ie_count--;
if (parse->rsn)
prot_ie_count--;
prot_ie_count--;
if (parse->mdie)
prot_ie_count--;
prot_ie_count--;
if (parse->ftie)
prot_ie_count--;
prot_ie_count--;
if (prot_ie_count < 0) {
wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
"the protected IE count");
return -1;
wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
"the protected IE count");
return -1;
}
if (prot_ie_count == 0 && parse->ric) {
@@ -225,9 +241,9 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
}
parse->ric_len = pos - parse->ric;
if (prot_ie_count) {
wpa_printf(MSG_DEBUG, "FT: %d protected IEs missing from "
"frame", (int) prot_ie_count);
return -1;
wpa_printf(MSG_DEBUG, "FT: %d protected IEs missing from "
"frame", (int) prot_ie_count);
return -1;
}
return 0;
@@ -326,6 +342,8 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s)
return WPA_KEY_MGMT_SAE;
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_SAE_EXT_KEY)
return WPA_KEY_MGMT_SAE_EXT_KEY;
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_SAE)
return WPA_KEY_MGMT_FT_SAE;
#endif /* CONFIG_WPA3_SAE */
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA256)
return WPA_KEY_MGMT_IEEE8021X_SHA256;
@@ -340,12 +358,6 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s)
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192)
return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
#endif
#ifdef CONFIG_WPA3_SAE
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_SAE)
return WPA_KEY_MGMT_SAE;
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_SAE_EXT_KEY)
return WPA_KEY_MGMT_SAE_EXT_KEY;
#endif /* CONFIG_WPA3_SAE */
#ifdef CONFIG_OWE_STA
if(RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OWE)
return WPA_KEY_MGMT_OWE;
@@ -943,6 +955,7 @@ int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
switch (akmp) {
#ifdef CONFIG_WPA3_SAE
case WPA_KEY_MGMT_SAE:
case WPA_KEY_MGMT_FT_SAE:
return omac1_aes_128(key, buf, len, mic);
case WPA_KEY_MGMT_SAE_EXT_KEY:
wpa_printf(MSG_DEBUG,
@@ -1730,14 +1743,14 @@ int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
if (*pos == WLAN_EID_RSN) {
ie->rsn_ie = pos;
ie->rsn_ie_len = pos[1] + 2;
#ifdef CONFIG_IEEE80211R_AP
#ifdef CONFIG_IEEE80211R
} else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
ie->mdie = pos;
ie->mdie_len = pos[1] + 2;
} else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) {
ie->ftie = pos;
ie->ftie_len = pos[1] + 2;
#endif /* CONFIG_IEEE80211R_AP */
#endif /* CONFIG_IEEE80211R */
} else if (*pos == WLAN_EID_RSNX) {
ie->rsnxe = pos;
ie->rsnxe_len = pos[1] + 2;

View File

@@ -137,6 +137,17 @@ RSN_SELECTOR(0x00, 0x0f, 0xac, 13)
#define FT_R1KH_ID_LEN 6
#define WPA_PMK_NAME_LEN 16
/* FTE - MIC Control - RSNXE Used */
#define FTE_MIC_CTRL_RSNXE_USED BIT(0)
#define FTE_MIC_CTRL_MIC_LEN_MASK (BIT(1) | BIT(2) | BIT(3))
#define FTE_MIC_CTRL_MIC_LEN_SHIFT 1
/* FTE - MIC Length subfield values */
enum ft_mic_len_subfield {
FTE_MIC_LEN_16 = 0,
FTE_MIC_LEN_24 = 1,
FTE_MIC_LEN_32 = 2,
};
/* IEEE 802.11, 8.5.2 EAPOL-Key frames */
#define WPA_KEY_INFO_TYPE_MASK ((u16) (BIT(0) | BIT(1) | BIT(2)))
@@ -337,6 +348,7 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr,
const u8 *mdie, size_t mdie_len,
const u8 *ftie, size_t ftie_len,
const u8 *rsnie, size_t rsnie_len,
const u8 *rsnxe, size_t rsnxe_len,
const u8 *ric, size_t ric_len, u8 *mic);
void wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
const u8 *ssid, size_t ssid_len,
@@ -425,6 +437,8 @@ struct wpa_ft_ies {
size_t igtk_len;
const u8 *ric;
size_t ric_len;
const u8 *rsnxe;
size_t rsnxe_len;
};
/* WPA3 specification - RSN Selection element */

View File

@@ -422,6 +422,17 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
//eapol_sm_notify_cached(sm->eapol);
#ifdef CONFIG_IEEE80211R
sm->xxkey_len = 0;
#ifdef CONFIG_WPA3_SAE
if (sm->key_mgmt == WPA_KEY_MGMT_FT_SAE && sm->pmk_len == PMK_LEN) {
/* Need to allow FT key derivation to proceed with
* PMK from SAE being used as the XXKey in cases where
* the PMKID in msg 1/4 matches the PMKSA entry that was
* just added based on SAE authentication for the
* initial mobility domain association. */
os_memcpy(sm->xxkey, sm->pmk, sm->pmk_len);
sm->xxkey_len = sm->pmk_len;
}
#endif
#endif /* CONFIG_IEEE80211R */
} else if (wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) {
int res = 0, pmk_len;
@@ -1348,6 +1359,133 @@ static void wpa_sm_set_seq(struct wpa_sm *sm, struct wpa_eapol_key *key, u8 ispt
memcpy(seq, key_rsc, WPA_KEY_RSC_LEN);
}
#ifdef CONFIG_IEEE80211R
static int ft_validate_mdie(struct wpa_sm *sm,
const unsigned char *src_addr,
struct wpa_eapol_ie_parse *ie,
const u8 *assoc_resp_mdie)
{
struct rsn_mdie *mdie;
mdie = (struct rsn_mdie *) (ie->mdie + 2);
if (ie->mdie == NULL || ie->mdie_len < 2 + sizeof(*mdie) ||
os_memcmp(mdie->mobility_domain, sm->mobility_domain,
MOBILITY_DOMAIN_ID_LEN) != 0) {
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE in msg 3/4 did "
"not match with the current mobility domain");
return -1;
}
if (assoc_resp_mdie &&
(assoc_resp_mdie[1] != ie->mdie[1] ||
os_memcmp(assoc_resp_mdie, ie->mdie, 2 + ie->mdie[1]) != 0)) {
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE mismatch");
wpa_hexdump(MSG_DEBUG, "FT: MDIE in EAPOL-Key msg 3/4",
ie->mdie, 2 + ie->mdie[1]);
wpa_hexdump(MSG_DEBUG, "FT: MDIE in (Re)Association Response",
assoc_resp_mdie, 2 + assoc_resp_mdie[1]);
return -1;
}
return 0;
}
static int ft_validate_ftie(struct wpa_sm *sm,
const unsigned char *src_addr,
struct wpa_eapol_ie_parse *ie,
const u8 *assoc_resp_ftie)
{
if (ie->ftie == NULL) {
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"FT: No FTIE in EAPOL-Key msg 3/4");
return -1;
}
if (assoc_resp_ftie == NULL)
return 0;
if (assoc_resp_ftie[1] != ie->ftie[1] ||
os_memcmp(assoc_resp_ftie, ie->ftie, 2 + ie->ftie[1]) != 0) {
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: FTIE mismatch");
wpa_hexdump(MSG_DEBUG, "FT: FTIE in EAPOL-Key msg 3/4",
ie->ftie, 2 + ie->ftie[1]);
wpa_hexdump(MSG_DEBUG, "FT: FTIE in (Re)Association Response",
assoc_resp_ftie, 2 + assoc_resp_ftie[1]);
return -1;
}
return 0;
}
static int ft_validate_rsnie(struct wpa_sm *sm,
const unsigned char *src_addr,
struct wpa_eapol_ie_parse *ie)
{
struct wpa_ie_data rsn;
if (!ie->rsn_ie)
return 0;
/*
* Verify that PMKR1Name from EAPOL-Key message 3/4
* matches with the value we derived.
*/
if (wpa_parse_wpa_ie_rsn(ie->rsn_ie, ie->rsn_ie_len, &rsn) < 0 ||
rsn.num_pmkid != 1 || rsn.pmkid == NULL) {
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: No PMKR1Name in "
"FT 4-way handshake message 3/4");
return -1;
}
if (os_memcmp_const(rsn.pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0)
{
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"FT: PMKR1Name mismatch in "
"FT 4-way handshake message 3/4");
wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from Authenticator",
rsn.pmkid, WPA_PMK_NAME_LEN);
wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name",
sm->pmk_r1_name, WPA_PMK_NAME_LEN);
return -1;
}
return 0;
}
static int wpa_supplicant_validate_ie_ft(struct wpa_sm *sm,
const unsigned char *src_addr,
struct wpa_eapol_ie_parse *ie)
{
const u8 *pos, *end, *mdie = NULL, *ftie = NULL;
if (sm->assoc_resp_ies) {
pos = sm->assoc_resp_ies;
end = pos + sm->assoc_resp_ies_len;
while (end - pos > 2) {
if (2 + pos[1] > end -pos)
break;
switch (*pos) {
case WLAN_EID_MOBILITY_DOMAIN:
mdie = pos;
break;
case WLAN_EID_FAST_BSS_TRANSITION:
ftie = pos;
break;
}
pos += 2 + pos[1];
}
}
if (ft_validate_mdie(sm, src_addr, ie, mdie) < 0 ||
ft_validate_ftie(sm, src_addr, ie, ftie) < 0 ||
ft_validate_rsnie(sm, src_addr, ie) < 0) {
return -1;
}
return 0;
}
#endif /* CONFIG_IEEE80211R */
static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
struct wpa_eapol_key *key,
u16 ver, const u8 *key_data,
@@ -1364,6 +1502,11 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) {
goto failed;
}
#ifdef CONFIG_IEEE80211R
if (wpa_key_mgmt_ft(sm->key_mgmt) && wpa_supplicant_validate_ie_ft(sm, sm->bssid, &ie) < 0) {
goto failed;
}
#endif /* CONFIG_IEEE80211R */
if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0) {
goto failed;
}
@@ -2453,6 +2596,8 @@ void wpa_set_profile(u32 wpa_proto, u8 auth_mode)
sm->key_mgmt = WPA_KEY_MGMT_SAE_EXT_KEY; /* for WPA3 PSK */
} else if (auth_mode == WPA3_AUTH_DPP) {
sm->key_mgmt = WPA_KEY_MGMT_DPP;
} else if (auth_mode == WPA3_AUTH_FT_SAE) {
sm->key_mgmt = WPA_KEY_MGMT_FT_SAE;
} else {
sm->key_mgmt = WPA_KEY_MGMT_PSK; /* fixed to PSK for now */
}
@@ -2497,7 +2642,7 @@ int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, uint8_t pairwise_cipher, uint8_
* is part of libraries,
* TODO Correct this in future during NVS restructuring */
if ((sm->key_mgmt == WPA_KEY_MGMT_SAE ||
sm->key_mgmt == WPA_KEY_MGMT_SAE_EXT_KEY) &&
sm->key_mgmt == WPA_KEY_MGMT_SAE_EXT_KEY || sm->key_mgmt == WPA_KEY_MGMT_FT_SAE) &&
(os_memcmp(sm->bssid, bssid, ETH_ALEN) == 0) &&
(os_memcmp(sm->ssid, ssid, ssid_len) != 0)) {
use_pmk_cache = false;
@@ -2580,7 +2725,7 @@ int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, uint8_t pairwise_cipher, uint8_
}
#endif
#ifdef CONFIG_IEEE80211R
if (sm->key_mgmt == WPA_KEY_MGMT_FT_PSK) {
if (sm->key_mgmt == WPA_KEY_MGMT_FT_PSK || sm->key_mgmt == WPA_KEY_MGMT_FT_SAE) {
const u8 *ie, *md = NULL;
struct wpa_bss *bss = wpa_bss_get_bssid(&g_wpa_supp, bssid);
if (!bss) {
@@ -2709,7 +2854,8 @@ void wpa_set_passphrase(char * passphrase, u8 *ssid, size_t ssid_len)
if (sm->key_mgmt == WPA_KEY_MGMT_SAE ||
sm->key_mgmt == WPA_KEY_MGMT_OWE ||
sm->key_mgmt == WPA_KEY_MGMT_SAE_EXT_KEY ||
sm->key_mgmt == WPA_KEY_MGMT_DPP)
sm->key_mgmt == WPA_KEY_MGMT_DPP ||
sm->key_mgmt == WPA_KEY_MGMT_FT_SAE)
return;
/* This is really SLOW, so just re cacl while reset param */

View File

@@ -15,6 +15,7 @@
#include "common/ieee802_11_common.h"
#include "wpa.h"
#include "wpa_i.h"
#include "wpa_ie.h"
#ifdef CONFIG_IEEE80211R
@@ -164,11 +165,16 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
struct rsn_ie_hdr *rsnie;
int mdie_len;
u16 capab;
int rsnxe_used;
size_t rsnxe_len;
u8 mic_control;
int res;
u8 rsnxe[20];
sm->ft_completed = 0;
buf_len = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) +
2 + sm->r0kh_id_len + ric_ies_len + 100;
2 + sm->r0kh_id_len + ric_ies_len + 100 + sizeof(rsnxe);
buf = os_zalloc(buf_len);
if (buf == NULL)
return NULL;
@@ -245,10 +251,20 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
pos += WPA_PMK_NAME_LEN;
#ifdef CONFIG_IEEE80211W
if (sm->mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) {
/* Management Group Cipher Suite */
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
pos += RSN_SELECTOR_LEN;
/* Management Group Cipher Suite */
switch (sm->mgmt_group_cipher) {
case WPA_CIPHER_AES_128_CMAC:
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
pos += RSN_SELECTOR_LEN;
break;
case WPA_CIPHER_BIP_GMAC_128:
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_128);
pos += RSN_SELECTOR_LEN;
break;
case WPA_CIPHER_BIP_GMAC_256:
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_256);
pos += RSN_SELECTOR_LEN;
break;
}
#endif /* CONFIG_IEEE80211W */
@@ -269,6 +285,10 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
ftie_len = pos++;
ftie = (struct rsn_ftie *) pos;
pos += sizeof(*ftie);
rsnxe_used = wpa_key_mgmt_sae(sm->key_mgmt) && anonce &&
(sm->sae_pwe == SAE_PWE_BOTH ||
sm->sae_pwe == SAE_PWE_HASH_TO_ELEMENT);
mic_control = rsnxe_used ? FTE_MIC_CTRL_RSNXE_USED : 0;
os_memcpy(ftie->snonce, sm->snonce, WPA_NONCE_LEN);
if (anonce)
os_memcpy(ftie->anonce, anonce, WPA_NONCE_LEN);
@@ -292,6 +312,15 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
pos += ric_ies_len;
}
res = wpa_gen_rsnxe(sm, rsnxe, sizeof(rsnxe));
if (res < 0) {
os_free(buf);
return NULL;
}
rsnxe_len = res;
os_memcpy(pos, rsnxe, rsnxe_len);
pos += rsnxe_len;
if (kck) {
/*
* IEEE Std 802.11r-2008, 11A.8.4
@@ -303,14 +332,20 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
* MDIE
* FTIE (with MIC field set to 0)
* RIC-Request (if present)
* RSNXE (if present)
*/
/* Information element count */
mic_control |= FTE_MIC_LEN_16 << FTE_MIC_CTRL_MIC_LEN_SHIFT;
ftie->mic_control[0] = mic_control;
ftie->mic_control[1] = 3 + ieee802_11_ie_count(ric_ies,
ric_ies_len);
if (rsnxe_len)
ftie->mic_control[1] += 1;
if (wpa_ft_mic(kck, kck_len, sm->own_addr, target_ap, 5,
((u8 *) mdie) - 2, 2 + sizeof(*mdie),
ftie_pos, 2 + *ftie_len,
(u8 *) rsnie, 2 + rsnie->len, ric_ies,
(u8 *) rsnie, 2 + rsnie->len,
rsnxe_len ? rsnxe : NULL, rsnxe_len, ric_ies,
ric_ies_len, ftie->mic) < 0) {
wpa_printf(MSG_INFO, "FT: Failed to calculate MIC");
os_free(buf);
@@ -660,6 +695,7 @@ static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem,
size_t igtk_elem_len)
{
u8 igtk[WPA_IGTK_LEN];
wifi_wpa_igtk_t *_igtk = (wifi_wpa_igtk_t*)igtk_elem;
if (sm->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC)
return 0;
@@ -692,12 +728,12 @@ static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem,
/* KeyID[2] | IPN[6] | Key Length[1] | Key[16+8] */
wpa_hexdump_key(MSG_DEBUG, "FT: IGTK from Reassoc Resp", igtk,
wpa_hexdump_key(MSG_DEBUG, "FT: IGTK from Reassoc Resp ", igtk,
WPA_IGTK_LEN);
#ifdef ESP_SUPPLICANT
if (esp_wifi_set_igtk_internal(WIFI_IF_STA, (wifi_wpa_igtk_t *)igtk) < 0) {
if (esp_wifi_set_igtk_internal(WIFI_IF_STA, (wifi_wpa_igtk_t *)_igtk) < 0) {
#else
keyidx = WPA_GET_LE16(igtk_elem);
keyidx = WPA_GET_LE16(igtk_elem);
if (wpa_sm_set_key(&(sm->install_gtk), WIFI_WPA_ALG_IGTK, sm->bssid, keyidx, 0,
(u8 *)(igtk_elem + 2), 6, igtk, WPA_IGTK_LEN, sm->key_entry_valid) < 0) {
#endif
@@ -809,6 +845,8 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
count = 3;
if (parse.ric)
count += ieee802_11_ie_count(parse.ric, parse.ric_len);
if (parse.rsnxe)
count++;
if (ftie->mic_control[1] != count) {
wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in MIC "
"Control: received %u expected %u",
@@ -820,6 +858,8 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
parse.mdie - 2, parse.mdie_len + 2,
parse.ftie - 2, parse.ftie_len + 2,
parse.rsn - 2, parse.rsn_len + 2,
parse.rsnxe ? parse.rsnxe - 2 : NULL,
parse.rsnxe ? parse.rsnxe_len + 2 : 0,
parse.ric, parse.ric_len,
mic) < 0) {
wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");

View File

@@ -203,6 +203,8 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE);
} else if (key_mgmt == WPA_KEY_MGMT_SAE_EXT_KEY) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE_EXT_KEY);
} else if (key_mgmt == WPA_KEY_MGMT_FT_SAE) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE);
#endif /* CONFIG_WPA3_SAE */
#ifdef CONFIG_OWE_STA
} else if (key_mgmt == WPA_KEY_MGMT_OWE) {