mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
feat(wifi): Add SAE-EXT-KEY feature on softAP
This commit is contained in:
@@ -247,9 +247,11 @@ void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
#endif /* ESP_SUPPLICANT */
|
||||
|
||||
sta->auth_alg = WLAN_AUTH_SAE;
|
||||
sta->sae->peer_commit_scalar_accepted = sta->sae->peer_commit_scalar;
|
||||
sta->sae->peer_commit_scalar = NULL;
|
||||
sae_set_state(sta, SAE_ACCEPTED, "Accept Confirm");
|
||||
wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
|
||||
sta->sae->pmk, sta->sae->pmkid, false);
|
||||
sta->sae->pmk, sta->sae->pmk_len, sta->sae->pmkid, false, sta->sae->akmp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -949,16 +949,16 @@ continue_processing:
|
||||
}
|
||||
|
||||
int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr,
|
||||
const u8 *pmk, const u8 *pmkid, bool cache_pmksa)
|
||||
const u8 *pmk, size_t pmk_len, const u8 *pmkid, bool cache_pmksa, int akmp)
|
||||
{
|
||||
if (cache_pmksa)
|
||||
return -1;
|
||||
|
||||
wpa_hexdump_key(MSG_DEBUG, "RSN: Cache PMK from SAE", pmk, PMK_LEN);
|
||||
if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, PMK_LEN, pmkid,
|
||||
if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, pmk_len, pmkid,
|
||||
NULL, 0,
|
||||
wpa_auth->addr, addr, 0, NULL,
|
||||
WPA_KEY_MGMT_SAE))
|
||||
akmp))
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
@@ -1599,7 +1599,7 @@ SM_STATE(WPA_PTK, PTKSTART)
|
||||
|
||||
|
||||
static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce,
|
||||
const u8 *pmk, struct wpa_ptk *ptk)
|
||||
const u8 *pmk, unsigned int pmk_len, struct wpa_ptk *ptk)
|
||||
{
|
||||
#ifdef CONFIG_IEEE80211R_AP
|
||||
size_t ptk_len = sm->pairwise != WPA_CIPHER_TKIP ? 48 : 64;
|
||||
@@ -1609,7 +1609,7 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce,
|
||||
return wpa_auth_derive_ptk_ft(sm, pmk, ptk);
|
||||
#endif /* CONFIG_IEEE80211R_AP */
|
||||
|
||||
return wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion",
|
||||
return wpa_pmk_to_ptk(pmk, pmk_len, "Pairwise key expansion",
|
||||
sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce,
|
||||
ptk, sm->wpa_key_mgmt, sm->pairwise);
|
||||
}
|
||||
@@ -1625,10 +1625,12 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
|
||||
struct wpa_eapol_key *key;
|
||||
struct wpa_eapol_ie_parse kde;
|
||||
|
||||
size_t pmk_len;
|
||||
SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk);
|
||||
sm->EAPOLKeyReceived = FALSE;
|
||||
sm->update_snonce = FALSE;
|
||||
os_memset(&PTK, 0, sizeof(PTK));
|
||||
pmk_len = PMK_LEN;
|
||||
|
||||
/* WPA with IEEE 802.1X: use the derived PMK from EAP
|
||||
* WPA-PSK: iterate through possible PSKs and select the one matching
|
||||
@@ -1643,15 +1645,17 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
pmk_len = sm->pmk_len;
|
||||
pmk = sm->PMK;
|
||||
}
|
||||
|
||||
if (!pmk && sm->pmksa) {
|
||||
wpa_printf(MSG_DEBUG, "WPA: Use PMK from PMKSA cache");
|
||||
pmk = sm->pmksa->pmk;
|
||||
pmk_len = sm->pmksa->pmk_len;
|
||||
}
|
||||
|
||||
wpa_derive_ptk(sm, sm->SNonce, pmk, &PTK);
|
||||
wpa_derive_ptk(sm, sm->SNonce, pmk, pmk_len, &PTK);
|
||||
|
||||
if (wpa_verify_key_mic(sm->wpa_key_mgmt, &PTK,
|
||||
sm->last_rx_eapol_key,
|
||||
@@ -1730,7 +1734,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
|
||||
/* PSK may have changed from the previous choice, so update
|
||||
* state machine data based on whatever PSK was selected here.
|
||||
*/
|
||||
memcpy(sm->PMK, pmk, PMK_LEN);
|
||||
memcpy(sm->PMK, pmk, pmk_len);
|
||||
}
|
||||
|
||||
sm->MICVerified = TRUE;
|
||||
@@ -1749,13 +1753,18 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING2)
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
|
||||
#define WPA_IGTK_KDE_PREFIX_LEN (2 + 6)
|
||||
|
||||
static int ieee80211w_kde_len(struct wpa_state_machine *sm)
|
||||
{
|
||||
size_t len = 0;
|
||||
struct wpa_authenticator *wpa_auth = sm->wpa_auth;
|
||||
if (sm->mgmt_frame_prot) {
|
||||
return 2 + RSN_SELECTOR_LEN + sizeof(struct wpa_igtk_kde);
|
||||
len += 2 + RSN_SELECTOR_LEN + WPA_IGTK_KDE_PREFIX_LEN;
|
||||
len += wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
@@ -1764,6 +1773,10 @@ static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos)
|
||||
struct wpa_igtk_kde igtk;
|
||||
struct wpa_group *gsm = sm->group;
|
||||
|
||||
struct wpa_authenticator *wpa_auth = sm->wpa_auth;
|
||||
struct wpa_auth_config *conf = &wpa_auth->conf;
|
||||
size_t len = wpa_cipher_key_len(conf->group_mgmt_cipher);
|
||||
|
||||
if (!sm->mgmt_frame_prot)
|
||||
return pos;
|
||||
|
||||
@@ -1772,17 +1785,17 @@ static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos)
|
||||
if (gsm->wpa_group_state != WPA_GROUP_SETKEYSDONE ||
|
||||
wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, igtk.pn) < 0)
|
||||
memset(igtk.pn, 0, sizeof(igtk.pn));
|
||||
memcpy(igtk.igtk, gsm->IGTK[gsm->GN_igtk - 4], WPA_IGTK_LEN);
|
||||
memcpy(igtk.igtk, gsm->IGTK[gsm->GN_igtk - 4], len);
|
||||
if (sm->wpa_auth->conf.disable_gtk) {
|
||||
/*
|
||||
* Provide unique random IGTK to each STA to prevent use of
|
||||
* IGTK in the BSS.
|
||||
*/
|
||||
if (os_get_random(igtk.igtk, WPA_IGTK_LEN) < 0)
|
||||
if (os_get_random(igtk.igtk, len) < 0)
|
||||
return pos;
|
||||
}
|
||||
pos = wpa_add_kde(pos, RSN_KEY_DATA_IGTK,
|
||||
(const u8 *) &igtk, sizeof(igtk), NULL, 0);
|
||||
(const u8 *) &igtk, WPA_IGTK_KDE_PREFIX_LEN + len, NULL, 0);
|
||||
|
||||
return pos;
|
||||
}
|
||||
@@ -2256,6 +2269,7 @@ static int wpa_gtk_update(struct wpa_authenticator *wpa_auth,
|
||||
struct wpa_group *group)
|
||||
{
|
||||
int ret = 0;
|
||||
size_t len;
|
||||
|
||||
memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN);
|
||||
inc_byte_array(group->Counter, WPA_NONCE_LEN);
|
||||
@@ -2269,15 +2283,16 @@ static int wpa_gtk_update(struct wpa_authenticator *wpa_auth,
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) {
|
||||
len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher);
|
||||
memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN);
|
||||
inc_byte_array(group->Counter, WPA_NONCE_LEN);
|
||||
if (wpa_gmk_to_gtk(group->GMK, "IGTK key expansion",
|
||||
wpa_auth->addr, group->GNonce,
|
||||
group->IGTK[group->GN_igtk - 4],
|
||||
WPA_IGTK_LEN) < 0)
|
||||
len) < 0)
|
||||
ret = -1;
|
||||
wpa_hexdump_key(MSG_DEBUG, "IGTK",
|
||||
group->IGTK[group->GN_igtk - 4], WPA_IGTK_LEN);
|
||||
group->IGTK[group->GN_igtk - 4], len);
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
|
||||
|
||||
@@ -300,7 +300,7 @@ int wpa_wnmsleep_igtk_subelem(struct wpa_state_machine *sm, u8 *pos);
|
||||
|
||||
int wpa_auth_uses_sae(struct wpa_state_machine *sm);
|
||||
int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr,
|
||||
const u8 *pmk, const u8 *pmkid,bool cache_pmksa);
|
||||
const u8 *pmk, size_t pmk_len, const u8 *pmkid,bool cache_pmksa, int akmp);
|
||||
void wpa_auth_add_sae_pmkid(struct wpa_state_machine *sm, const u8 *pmkid);
|
||||
void wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth,
|
||||
const u8 *sta_addr);
|
||||
|
||||
@@ -195,7 +195,7 @@ struct wpa_authenticator {
|
||||
|
||||
|
||||
int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
|
||||
const u8 *pmkid);
|
||||
const u8 *pmkid, int group_mgmt_cipher);
|
||||
int wpa_write_rsnxe(struct wpa_auth_config *conf, u8 *buf, size_t len);
|
||||
void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
|
||||
struct wpa_state_machine *sm, int key_info,
|
||||
|
||||
@@ -86,7 +86,7 @@ static int wpa_write_wpa_ie(struct wpa_auth_config *conf, u8 *buf, size_t len)
|
||||
|
||||
|
||||
int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
|
||||
const u8 *pmkid)
|
||||
const u8 *pmkid, int group_mgmt_cipher)
|
||||
{
|
||||
struct rsn_ie_hdr *hdr;
|
||||
int num_suites, res;
|
||||
@@ -191,6 +191,11 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
|
||||
pos += RSN_SELECTOR_LEN;
|
||||
num_suites++;
|
||||
}
|
||||
if (conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY) {
|
||||
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE_EXT_KEY);
|
||||
pos += RSN_SELECTOR_LEN;
|
||||
num_suites++;
|
||||
}
|
||||
if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_SAE) {
|
||||
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE);
|
||||
pos += RSN_SELECTOR_LEN;
|
||||
@@ -265,8 +270,20 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
|
||||
}
|
||||
|
||||
/* Management Group Cipher Suite */
|
||||
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
|
||||
pos += RSN_SELECTOR_LEN;
|
||||
switch (group_mgmt_cipher) {
|
||||
case WPA_CIPHER_AES_128_CMAC:
|
||||
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
|
||||
break;
|
||||
case WPA_CIPHER_BIP_GMAC_128:
|
||||
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_128);
|
||||
break;
|
||||
case WPA_CIPHER_BIP_GMAC_256:
|
||||
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_256);
|
||||
break;
|
||||
default:
|
||||
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
|
||||
}
|
||||
pos += RSN_SELECTOR_LEN;
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
|
||||
@@ -335,7 +352,7 @@ int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth)
|
||||
|
||||
if (wpa_auth->conf.wpa & WPA_PROTO_RSN) {
|
||||
res = wpa_write_rsn_ie(&wpa_auth->conf,
|
||||
pos, buf + sizeof(buf) - pos, NULL);
|
||||
pos, buf + sizeof(buf) - pos, NULL, wpa_auth->conf.group_mgmt_cipher);
|
||||
if (res < 0)
|
||||
return res;
|
||||
pos += res;
|
||||
@@ -443,6 +460,8 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
|
||||
#ifdef CONFIG_SAE
|
||||
else if (data.key_mgmt & WPA_KEY_MGMT_SAE)
|
||||
selector = RSN_AUTH_KEY_MGMT_SAE;
|
||||
else if (data.key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY)
|
||||
selector = RSN_AUTH_KEY_MGMT_SAE_EXT_KEY;
|
||||
else if (data.key_mgmt & WPA_KEY_MGMT_FT_SAE)
|
||||
selector = RSN_AUTH_KEY_MGMT_FT_SAE;
|
||||
#endif /* CONFIG_SAE */
|
||||
@@ -518,6 +537,8 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
|
||||
#ifdef CONFIG_SAE
|
||||
else if (key_mgmt & WPA_KEY_MGMT_SAE)
|
||||
sm->wpa_key_mgmt = WPA_KEY_MGMT_SAE;
|
||||
else if (key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY)
|
||||
sm->wpa_key_mgmt = WPA_KEY_MGMT_SAE_EXT_KEY;
|
||||
else if (key_mgmt & WPA_KEY_MGMT_FT_SAE)
|
||||
sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_SAE;
|
||||
#endif /* CONFIG_SAE */
|
||||
@@ -563,10 +584,8 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
|
||||
"cannot use TKIP");
|
||||
return WPA_MGMT_FRAME_PROTECTION_VIOLATION;
|
||||
}
|
||||
|
||||
if (data.mgmt_group_cipher != wpa_auth->conf.group_mgmt_cipher)
|
||||
{
|
||||
wpa_printf(MSG_DEBUG, "Unsupported management group "
|
||||
if (!wpa_cipher_valid_mgmt_group(data.mgmt_group_cipher)) {
|
||||
wpa_printf( MSG_DEBUG, "Unsupported management group "
|
||||
"cipher %d", data.mgmt_group_cipher);
|
||||
return WPA_INVALID_MGMT_GROUP_CIPHER;
|
||||
}
|
||||
@@ -610,6 +629,8 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
|
||||
sm->pairwise = WPA_CIPHER_CCMP;
|
||||
else if (ciphers & WPA_CIPHER_GCMP)
|
||||
sm->pairwise = WPA_CIPHER_GCMP;
|
||||
else if (ciphers & WPA_CIPHER_GCMP_256)
|
||||
sm->pairwise = WPA_CIPHER_GCMP_256;
|
||||
else
|
||||
sm->pairwise = WPA_CIPHER_TKIP;
|
||||
|
||||
@@ -636,7 +657,7 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SAE
|
||||
if (sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE && data.num_pmkid &&
|
||||
if ((sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE || sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE_EXT_KEY) && data.num_pmkid &&
|
||||
!sm->pmksa) {
|
||||
wpa_printf(MSG_DEBUG, "No PMKSA cache entry found for SAE");
|
||||
return WPA_INVALID_PMKID;
|
||||
|
||||
@@ -324,6 +324,8 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s)
|
||||
#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 */
|
||||
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA256)
|
||||
return WPA_KEY_MGMT_IEEE8021X_SHA256;
|
||||
|
||||
Reference in New Issue
Block a user