mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 18:10:57 +02:00
Merge branch 'feat/ft_with_sae' into 'master'
Add FT with SAE feature for station See merge request espressif/esp-idf!39994
This commit is contained in:
Submodule components/esp_wifi/lib updated: c0ea1c78c6...700b098c7b
@@ -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);
|
||||
|
@@ -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
|
||||
};
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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 */
|
||||
|
@@ -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 */
|
||||
|
@@ -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");
|
||||
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user