FILS: Fix Key-Auth derivation for SK+PFS for authenticator side

The conditional gSTA and gAP (DH public keys) were not previously
included in Key-Auth derivation, but they are needed for the PFS case.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2017-05-07 17:04:08 +03:00
parent e6b6231338
commit 80ddf5d995
5 changed files with 14 additions and 4 deletions

View file

@ -1096,6 +1096,8 @@ void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
goto fail; goto fail;
} }
wpabuf_free(sta->fils_g_sta);
sta->fils_g_sta = wpabuf_alloc_copy(pos, elem_len);
wpabuf_clear_free(sta->fils_dh_ss); wpabuf_clear_free(sta->fils_dh_ss);
sta->fils_dh_ss = crypto_ecdh_set_peerkey(sta->fils_ecdh, 1, sta->fils_dh_ss = crypto_ecdh_set_peerkey(sta->fils_ecdh, 1,
pos, elem_len); pos, elem_len);
@ -1395,7 +1397,8 @@ prepare_auth_resp_fils(struct hostapd_data *hapd,
} }
if (fils_auth_pmk_to_ptk(sta->wpa_sm, pmk, pmk_len, if (fils_auth_pmk_to_ptk(sta->wpa_sm, pmk, pmk_len,
sta->fils_snonce, fils_nonce) < 0) { sta->fils_snonce, fils_nonce,
sta->fils_g_sta, pub) < 0) {
*resp = WLAN_STATUS_UNSPECIFIED_FAILURE; *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
wpabuf_free(data); wpabuf_free(data);
data = NULL; data = NULL;

View file

@ -348,6 +348,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
#ifdef CONFIG_FILS_SK_PFS #ifdef CONFIG_FILS_SK_PFS
crypto_ecdh_deinit(sta->fils_ecdh); crypto_ecdh_deinit(sta->fils_ecdh);
wpabuf_clear_free(sta->fils_dh_ss); wpabuf_clear_free(sta->fils_dh_ss);
wpabuf_free(sta->fils_g_sta);
#endif /* CONFIG_FILS_SK_PFS */ #endif /* CONFIG_FILS_SK_PFS */
#endif /* CONFIG_FILS */ #endif /* CONFIG_FILS */

View file

@ -238,6 +238,7 @@ struct sta_info {
struct crypto_ecdh *fils_ecdh; struct crypto_ecdh *fils_ecdh;
#endif /* CONFIG_FILS_SK_PFS */ #endif /* CONFIG_FILS_SK_PFS */
struct wpabuf *fils_dh_ss; struct wpabuf *fils_dh_ss;
struct wpabuf *fils_g_sta;
#endif /* CONFIG_FILS */ #endif /* CONFIG_FILS */
#ifdef CONFIG_OWE #ifdef CONFIG_OWE

View file

@ -2083,7 +2083,8 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce,
#ifdef CONFIG_FILS #ifdef CONFIG_FILS
int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk, int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk,
size_t pmk_len, const u8 *snonce, const u8 *anonce) size_t pmk_len, const u8 *snonce, const u8 *anonce,
struct wpabuf *g_sta, struct wpabuf *g_ap)
{ {
u8 ick[FILS_ICK_MAX_LEN]; u8 ick[FILS_ICK_MAX_LEN];
size_t ick_len; size_t ick_len;
@ -2098,7 +2099,10 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk,
res = fils_key_auth_sk(ick, ick_len, snonce, anonce, res = fils_key_auth_sk(ick, ick_len, snonce, anonce,
sm->addr, sm->wpa_auth->addr, sm->addr, sm->wpa_auth->addr,
NULL, 0, NULL, 0, /* TODO: SK+PFS */ g_sta ? wpabuf_head(g_sta) : NULL,
g_sta ? wpabuf_len(g_sta) : 0,
g_ap ? wpabuf_head(g_ap) : NULL,
g_ap ? wpabuf_len(g_ap) : 0,
sm->wpa_key_mgmt, sm->fils_key_auth_sta, sm->wpa_key_mgmt, sm->fils_key_auth_sta,
sm->fils_key_auth_ap, sm->fils_key_auth_ap,
&sm->fils_key_auth_len); &sm->fils_key_auth_len);

View file

@ -396,7 +396,8 @@ void wpa_auth_reconfig_group_keys(struct wpa_authenticator *wpa_auth);
int wpa_auth_ensure_group(struct wpa_authenticator *wpa_auth, int vlan_id); int wpa_auth_ensure_group(struct wpa_authenticator *wpa_auth, int vlan_id);
int wpa_auth_release_group(struct wpa_authenticator *wpa_auth, int vlan_id); int wpa_auth_release_group(struct wpa_authenticator *wpa_auth, int vlan_id);
int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk, int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk,
size_t pmk_len, const u8 *snonce, const u8 *anonce); size_t pmk_len, const u8 *snonce, const u8 *anonce,
struct wpabuf *g_sta, struct wpabuf *g_ap);
int fils_decrypt_assoc(struct wpa_state_machine *sm, const u8 *fils_session, int fils_decrypt_assoc(struct wpa_state_machine *sm, const u8 *fils_session,
const struct ieee80211_mgmt *mgmt, size_t frame_len, const struct ieee80211_mgmt *mgmt, size_t frame_len,
u8 *pos, size_t left); u8 *pos, size_t left);