mesh: Add support for PMKSA caching
This patch add functionality of mesh SAE PMKSA caching. If the local STA
already has peer's PMKSA entry in the cache, skip SAE authentication and
start AMPE with the cached value.
If the peer does not support PMKSA caching or does not have the local
STA's PMKSA entry in the cache, AMPE will fail and the PMKSA cache entry
of the peer will be removed. Then STA retries with ordinary SAE
authentication.
If the peer does not support PMKSA caching and the local STA uses
no_auto_peer=1, the local STA can not retry SAE authentication because
NEW_PEER_CANDIDATE event cannot start SAE authentication when
no_auto_peer=1. So this patch extends MESH_PEER_ADD command to use
duration(sec). Throughout the duration, the local STA can start SAE
authentication triggered by NEW_PEER_CANDIDATE even though
no_auto_peer=1.
This commit requires commit 70c93963ed
('SAE: Fix PMKID calculation for PMKSA cache'). Without that commit,
chosen PMK comparison will fail.
Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
This commit is contained in:
parent
4c522c7798
commit
9f2cf23e2e
13 changed files with 147 additions and 18 deletions
|
@ -262,6 +262,7 @@ struct hostapd_data {
|
|||
struct sta_info *sta);
|
||||
struct wpabuf *mesh_pending_auth;
|
||||
struct os_reltime mesh_pending_auth_time;
|
||||
u8 mesh_required_peer[ETH_ALEN];
|
||||
#endif /* CONFIG_MESH */
|
||||
|
||||
#ifdef CONFIG_SQLITE
|
||||
|
|
|
@ -554,6 +554,18 @@ static void sae_set_retransmit_timer(struct hostapd_data *hapd,
|
|||
}
|
||||
|
||||
|
||||
void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
{
|
||||
sta->flags |= WLAN_STA_AUTH;
|
||||
sta->auth_alg = WLAN_AUTH_SAE;
|
||||
mlme_authenticate_indication(hapd, sta);
|
||||
wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
|
||||
sta->sae->state = SAE_ACCEPTED;
|
||||
wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
|
||||
sta->sae->pmk, sta->sae->pmkid);
|
||||
}
|
||||
|
||||
|
||||
static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
const u8 *bssid, u8 auth_transaction)
|
||||
{
|
||||
|
@ -676,13 +688,7 @@ static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
|
|||
|
||||
sae_set_retransmit_timer(hapd, sta);
|
||||
} else {
|
||||
sta->flags |= WLAN_STA_AUTH;
|
||||
sta->auth_alg = WLAN_AUTH_SAE;
|
||||
mlme_authenticate_indication(hapd, sta);
|
||||
wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
|
||||
sta->sae->state = SAE_ACCEPTED;
|
||||
wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
|
||||
sta->sae->pmk, sta->sae->pmkid);
|
||||
sae_accept_sta(hapd, sta);
|
||||
}
|
||||
break;
|
||||
case SAE_ACCEPTED:
|
||||
|
@ -691,6 +697,7 @@ static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
|
|||
") doing reauthentication",
|
||||
MAC2STR(sta->addr));
|
||||
ap_free_sta(hapd, sta);
|
||||
wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
|
||||
} else {
|
||||
if (sae_check_big_sync(sta))
|
||||
return WLAN_STATUS_SUCCESS;
|
||||
|
@ -733,6 +740,13 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
|
|||
sta->sae->sync = 0;
|
||||
}
|
||||
|
||||
if (sta->mesh_sae_pmksa_caching) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
|
||||
wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
|
||||
sta->mesh_sae_pmksa_caching = 0;
|
||||
}
|
||||
|
||||
if (auth_transaction == 1) {
|
||||
const u8 *token = NULL, *pos, *end;
|
||||
size_t token_len = 0;
|
||||
|
|
|
@ -102,6 +102,7 @@ int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta);
|
|||
#ifdef CONFIG_SAE
|
||||
void sae_clear_retransmit_timer(struct hostapd_data *hapd,
|
||||
struct sta_info *sta);
|
||||
void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
#else /* CONFIG_SAE */
|
||||
static inline void sae_clear_retransmit_timer(struct hostapd_data *hapd,
|
||||
struct sta_info *sta)
|
||||
|
|
|
@ -183,6 +183,7 @@ struct sta_info {
|
|||
|
||||
#ifdef CONFIG_SAE
|
||||
struct sae_data *sae;
|
||||
unsigned int mesh_sae_pmksa_caching:1;
|
||||
#endif /* CONFIG_SAE */
|
||||
|
||||
u32 session_timeout; /* valid only if session_timeout_set == 1 */
|
||||
|
|
|
@ -3375,6 +3375,34 @@ void wpa_auth_pmksa_flush(struct wpa_authenticator *wpa_auth)
|
|||
}
|
||||
|
||||
|
||||
struct rsn_pmksa_cache_entry *
|
||||
wpa_auth_pmksa_get(struct wpa_authenticator *wpa_auth, const u8 *sta_addr)
|
||||
{
|
||||
if (!wpa_auth || !wpa_auth->pmksa)
|
||||
return NULL;
|
||||
return pmksa_cache_auth_get(wpa_auth->pmksa, sta_addr, NULL);
|
||||
}
|
||||
|
||||
|
||||
void wpa_auth_pmksa_set_to_sm(struct rsn_pmksa_cache_entry *pmksa,
|
||||
struct wpa_state_machine *sm,
|
||||
struct wpa_authenticator *wpa_auth,
|
||||
u8 *pmkid, u8 *pmk)
|
||||
{
|
||||
if (!sm)
|
||||
return;
|
||||
|
||||
sm->pmksa = pmksa;
|
||||
if (sm->pmksa->pmk)
|
||||
os_memcpy(pmk, sm->pmksa->pmk, PMK_LEN);
|
||||
if (sm->pmksa->pmkid) {
|
||||
os_memcpy(pmkid, sm->pmksa->pmkid, PMKID_LEN);
|
||||
os_memcpy(wpa_auth->dot11RSNAPMKIDUsed,
|
||||
sm->pmksa->pmkid, PMKID_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Remove and free the group from wpa_authenticator. This is triggered by a
|
||||
* callback to make sure nobody is currently iterating the group list while it
|
||||
|
|
|
@ -301,6 +301,12 @@ void wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth,
|
|||
int wpa_auth_pmksa_list(struct wpa_authenticator *wpa_auth, char *buf,
|
||||
size_t len);
|
||||
void wpa_auth_pmksa_flush(struct wpa_authenticator *wpa_auth);
|
||||
struct rsn_pmksa_cache_entry *
|
||||
wpa_auth_pmksa_get(struct wpa_authenticator *wpa_auth, const u8 *sta_addr);
|
||||
void wpa_auth_pmksa_set_to_sm(struct rsn_pmksa_cache_entry *pmksa,
|
||||
struct wpa_state_machine *sm,
|
||||
struct wpa_authenticator *wpa_auth,
|
||||
u8 *pmkid, u8 *pmk);
|
||||
int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id);
|
||||
void wpa_auth_eapol_key_tx_status(struct wpa_authenticator *wpa_auth,
|
||||
struct wpa_state_machine *sm, int ack);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue