Browse Source

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>
Jouni Malinen 7 years ago
parent
commit
80ddf5d995
5 changed files with 14 additions and 4 deletions
  1. 4 1
      src/ap/ieee802_11.c
  2. 1 0
      src/ap/sta_info.c
  3. 1 0
      src/ap/sta_info.h
  4. 6 2
      src/ap/wpa_auth.c
  5. 2 1
      src/ap/wpa_auth.h

+ 4 - 1
src/ap/ieee802_11.c

@@ -1096,6 +1096,8 @@ void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
 			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);
 		sta->fils_dh_ss = crypto_ecdh_set_peerkey(sta->fils_ecdh, 1,
 							  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,
-				 sta->fils_snonce, fils_nonce) < 0) {
+				 sta->fils_snonce, fils_nonce,
+				 sta->fils_g_sta, pub) < 0) {
 		*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
 		wpabuf_free(data);
 		data = NULL;

+ 1 - 0
src/ap/sta_info.c

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

+ 1 - 0
src/ap/sta_info.h

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

+ 6 - 2
src/ap/wpa_auth.c

@@ -2083,7 +2083,8 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce,
 #ifdef CONFIG_FILS
 
 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];
 	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,
 			       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->fils_key_auth_ap,
 			       &sm->fils_key_auth_len);

+ 2 - 1
src/ap/wpa_auth.h

@@ -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_release_group(struct wpa_authenticator *wpa_auth, int vlan_id);
 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,
 		       const struct ieee80211_mgmt *mgmt, size_t frame_len,
 		       u8 *pos, size_t left);