SAE: Clear keys from memory on disassociation

There is no need to keep temporary keys in memory beyond the end of the
association, so explicitly clear any SAE buffers that can contain keys
as soon as such keys are not needed.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2014-12-29 18:40:10 +02:00
parent fbfc974c6c
commit 4e70bbf1c6
4 changed files with 25 additions and 15 deletions

View file

@ -88,7 +88,7 @@ void sae_clear_temp_data(struct sae_data *sae)
crypto_ec_point_deinit(tmp->own_commit_element_ecc, 0); crypto_ec_point_deinit(tmp->own_commit_element_ecc, 0);
crypto_ec_point_deinit(tmp->peer_commit_element_ecc, 0); crypto_ec_point_deinit(tmp->peer_commit_element_ecc, 0);
wpabuf_free(tmp->anti_clogging_token); wpabuf_free(tmp->anti_clogging_token);
os_free(sae->tmp); bin_clear_free(tmp, sizeof(*tmp));
sae->tmp = NULL; sae->tmp = NULL;
} }
@ -624,8 +624,10 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k)
wpa_hexdump(MSG_DEBUG, "SAE: PMKID", val, SAE_PMKID_LEN); wpa_hexdump(MSG_DEBUG, "SAE: PMKID", val, SAE_PMKID_LEN);
sha256_prf(keyseed, sizeof(keyseed), "SAE KCK and PMK", sha256_prf(keyseed, sizeof(keyseed), "SAE KCK and PMK",
val, sae->tmp->prime_len, keys, sizeof(keys)); val, sae->tmp->prime_len, keys, sizeof(keys));
os_memset(keyseed, 0, sizeof(keyseed));
os_memcpy(sae->tmp->kck, keys, SAE_KCK_LEN); os_memcpy(sae->tmp->kck, keys, SAE_KCK_LEN);
os_memcpy(sae->pmk, keys + SAE_KCK_LEN, SAE_PMK_LEN); os_memcpy(sae->pmk, keys + SAE_KCK_LEN, SAE_PMK_LEN);
os_memset(keys, 0, sizeof(keys));
wpa_hexdump_key(MSG_DEBUG, "SAE: KCK", sae->tmp->kck, SAE_KCK_LEN); wpa_hexdump_key(MSG_DEBUG, "SAE: KCK", sae->tmp->kck, SAE_KCK_LEN);
wpa_hexdump_key(MSG_DEBUG, "SAE: PMK", sae->pmk, SAE_PMK_LEN); wpa_hexdump_key(MSG_DEBUG, "SAE: PMK", sae->pmk, SAE_PMK_LEN);

View file

@ -202,20 +202,12 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
bssid_changed = !is_zero_ether_addr(wpa_s->bssid); bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
os_memset(wpa_s->bssid, 0, ETH_ALEN); os_memset(wpa_s->bssid, 0, ETH_ALEN);
os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
#ifdef CONFIG_SME sme_clear_on_disassoc(wpa_s);
wpa_s->sme.prev_bssid_set = 0;
#endif /* CONFIG_SME */
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN); os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
wpa_s->current_bss = NULL; wpa_s->current_bss = NULL;
wpa_s->assoc_freq = 0; wpa_s->assoc_freq = 0;
#ifdef CONFIG_IEEE80211R
#ifdef CONFIG_SME
if (wpa_s->sme.ft_ies)
sme_update_ft_ies(wpa_s, NULL, NULL, 0);
#endif /* CONFIG_SME */
#endif /* CONFIG_IEEE80211R */
if (bssid_changed) if (bssid_changed)
wpas_notify_bssid_changed(wpa_s); wpas_notify_bssid_changed(wpa_s);

View file

@ -1099,6 +1099,21 @@ void sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s,
} }
void sme_clear_on_disassoc(struct wpa_supplicant *wpa_s)
{
wpa_s->sme.prev_bssid_set = 0;
#ifdef CONFIG_SAE
wpabuf_free(wpa_s->sme.sae_token);
wpa_s->sme.sae_token = NULL;
sae_clear_data(&wpa_s->sme.sae);
#endif /* CONFIG_SAE */
#ifdef CONFIG_IEEE80211R
if (wpa_s->sme.ft_ies)
sme_update_ft_ies(wpa_s, NULL, NULL, 0);
#endif /* CONFIG_IEEE80211R */
}
void sme_deinit(struct wpa_supplicant *wpa_s) void sme_deinit(struct wpa_supplicant *wpa_s)
{ {
os_free(wpa_s->sme.ft_ies); os_free(wpa_s->sme.ft_ies);
@ -1107,11 +1122,7 @@ void sme_deinit(struct wpa_supplicant *wpa_s)
#ifdef CONFIG_IEEE80211W #ifdef CONFIG_IEEE80211W
sme_stop_sa_query(wpa_s); sme_stop_sa_query(wpa_s);
#endif /* CONFIG_IEEE80211W */ #endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_SAE sme_clear_on_disassoc(wpa_s);
wpabuf_free(wpa_s->sme.sae_token);
wpa_s->sme.sae_token = NULL;
sae_clear_data(&wpa_s->sme.sae);
#endif /* CONFIG_SAE */
eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL); eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);

View file

@ -33,6 +33,7 @@ void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa,
void sme_state_changed(struct wpa_supplicant *wpa_s); void sme_state_changed(struct wpa_supplicant *wpa_s);
void sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s, void sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s,
const u8 *prev_pending_bssid); const u8 *prev_pending_bssid);
void sme_clear_on_disassoc(struct wpa_supplicant *wpa_s);
void sme_deinit(struct wpa_supplicant *wpa_s); void sme_deinit(struct wpa_supplicant *wpa_s);
int sme_proc_obss_scan(struct wpa_supplicant *wpa_s); int sme_proc_obss_scan(struct wpa_supplicant *wpa_s);
@ -94,6 +95,10 @@ sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s,
{ {
} }
static inline void sme_clear_on_disassoc(struct wpa_supplicant *wpa_s)
{
}
static inline void sme_deinit(struct wpa_supplicant *wpa_s) static inline void sme_deinit(struct wpa_supplicant *wpa_s)
{ {
} }