]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP: Support PASN with FT key derivation
authorIlan Peer <ilan.peer@intel.com>
Wed, 16 Dec 2020 11:01:04 +0000 (13:01 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 26 Jan 2021 15:49:00 +0000 (17:49 +0200)
Note that the implementation is not complete as it is missing support
for the FT wrapped data which is optional for the station, but must be
supported by the AP in case the station included it.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
src/ap/ieee802_11.c
src/ap/wpa_auth.h
src/ap/wpa_auth_ft.c

index 42d5cee5c4d9337de592440f604a3bd006fb9d41..f5b87fbf536d8f680a0cd157c59c3b4a8d68c933 100644 (file)
@@ -2811,7 +2811,7 @@ static struct wpabuf * pasn_get_wrapped_data(struct hostapd_data *hapd,
 
 static int
 pasn_derive_keys(struct hostapd_data *hapd, struct sta_info *sta,
-                struct rsn_pmksa_cache_entry *pmksa,
+                const u8 *cached_pmk, size_t cached_pmk_len,
                 struct wpa_pasn_params_data *pasn_data,
                 struct wpabuf *wrapped_data,
                 struct wpabuf *secret)
@@ -2824,7 +2824,7 @@ pasn_derive_keys(struct hostapd_data *hapd, struct sta_info *sta,
        os_memset(pmk, 0, sizeof(pmk));
        pmk_len = 0;
 
-       if (!pmksa)
+       if (!cached_pmk || !cached_pmk_len)
                wpa_printf(MSG_DEBUG, "PASN: No valid PMKSA entry");
 
        if (sta->pasn->akmp == WPA_KEY_MGMT_PASN) {
@@ -2832,11 +2832,11 @@ pasn_derive_keys(struct hostapd_data *hapd, struct sta_info *sta,
 
                pmk_len = WPA_PASN_PMK_LEN;
                os_memcpy(pmk, pasn_default_pmk, sizeof(pasn_default_pmk));
-       } else if (pmksa) {
+       } else if (cached_pmk && cached_pmk_len) {
                wpa_printf(MSG_DEBUG, "PASN: Using PMKSA entry");
 
-               pmk_len = pmksa->pmk_len;
-               os_memcpy(pmk, pmksa->pmk, pmksa->pmk_len);
+               pmk_len = cached_pmk_len;
+               os_memcpy(pmk, cached_pmk, cached_pmk_len);
        } else {
                switch (sta->pasn->akmp) {
 #ifdef CONFIG_SAE
@@ -2983,6 +2983,12 @@ static void handle_auth_pasn_1(struct hostapd_data *hapd, struct sta_info *sta,
        struct wpa_ie_data rsn_data;
        struct wpa_pasn_params_data pasn_params;
        struct rsn_pmksa_cache_entry *pmksa = NULL;
+       const u8 *cached_pmk = NULL;
+       size_t cached_pmk_len = 0;
+#ifdef CONFIG_IEEE80211R_AP
+       u8 pmk_r1[PMK_LEN_MAX];
+       size_t pmk_r1_len;
+#endif /* CONFIG_IEEE80211R_AP */
        struct wpabuf *wrapped_data = NULL, *secret = NULL;
        const int *groups = hapd->conf->pasn_groups;
        static const int default_groups[] = { 19, 0 };
@@ -3145,17 +3151,44 @@ static void handle_auth_pasn_1(struct hostapd_data *hapd, struct sta_info *sta,
        }
 
        if (rsn_data.num_pmkid) {
-               wpa_printf(MSG_DEBUG, "PASN: Try to find PMKSA entry");
+               if (wpa_key_mgmt_ft(sta->pasn->akmp)) {
+#ifdef CONFIG_IEEE80211R_AP
+                       wpa_printf(MSG_DEBUG, "PASN: FT: Fetch PMK-R1");
+
+                       ret = wpa_ft_fetch_pmk_r1(hapd->wpa_auth, sta->addr,
+                                                 rsn_data.pmkid,
+                                                 pmk_r1, &pmk_r1_len, NULL,
+                                                 NULL, NULL, NULL,
+                                                 NULL, NULL, NULL);
+                       if (ret) {
+                               wpa_printf(MSG_DEBUG,
+                                          "PASN: FT: Failed getting PMK-R1");
+                               status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+                               goto send_resp;
+                       }
+                       cached_pmk = pmk_r1;
+                       cached_pmk_len = pmk_r1_len;
+#else /* CONFIG_IEEE80211R_AP */
+                       wpa_printf(MSG_DEBUG, "PASN: FT: Not supported");
+                       status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+                       goto send_resp;
+#endif /* CONFIG_IEEE80211R_AP */
+               } else {
+                       wpa_printf(MSG_DEBUG, "PASN: Try to find PMKSA entry");
 
-               pmksa = wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr,
-                                          rsn_data.pmkid);
+                       pmksa = wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr,
+                                                  rsn_data.pmkid);
+                       if (pmksa) {
+                               cached_pmk = pmksa->pmk;
+                               cached_pmk_len = pmksa->pmk_len;
+                       }
+               }
        } else {
                wpa_printf(MSG_DEBUG, "PASN: No PMKID specified");
-               pmksa = NULL;
        }
 
-       ret = pasn_derive_keys(hapd, sta, pmksa, &pasn_params,
-                              wrapped_data, secret);
+       ret = pasn_derive_keys(hapd, sta, cached_pmk, cached_pmk_len,
+                              &pasn_params, wrapped_data, secret);
        if (ret) {
                wpa_printf(MSG_DEBUG, "PASN: Failed to derive keys");
                status = WLAN_STATUS_UNSPECIFIED_FAILURE;
index 0f91e3ee5ee38dd0e1422baad845648012f41f5b..0a5ba2ec7000361c9249879c7dfc47f4f4b993d2 100644 (file)
@@ -468,6 +468,14 @@ void wpa_ft_rrb_oui_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr,
 void wpa_ft_push_pmk_r1(struct wpa_authenticator *wpa_auth, const u8 *addr);
 void wpa_ft_deinit(struct wpa_authenticator *wpa_auth);
 void wpa_ft_sta_deinit(struct wpa_state_machine *sm);
+int wpa_ft_fetch_pmk_r1(struct wpa_authenticator *wpa_auth,
+                       const u8 *spa, const u8 *pmk_r1_name,
+                       u8 *pmk_r1, size_t *pmk_r1_len, int *pairwise,
+                       struct vlan_description *vlan,
+                       const u8 **identity, size_t *identity_len,
+                       const u8 **radius_cui, size_t *radius_cui_len,
+                       int *session_timeout);
+
 #endif /* CONFIG_IEEE80211R_AP */
 
 void wpa_wnmsleep_rekey_gtk(struct wpa_state_machine *sm);
index 9a1922e64ad761b2611d95aeec9b1b3565bb95f3..115a6fa2f3ba05d2d4816fc94426c1b6e653e252 100644 (file)
@@ -1473,13 +1473,13 @@ static int wpa_ft_store_pmk_r1(struct wpa_authenticator *wpa_auth,
 }
 
 
-static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator *wpa_auth,
-                              const u8 *spa, const u8 *pmk_r1_name,
-                              u8 *pmk_r1, size_t *pmk_r1_len, int *pairwise,
-                              struct vlan_description *vlan,
-                              const u8 **identity, size_t *identity_len,
-                              const u8 **radius_cui, size_t *radius_cui_len,
-                              int *session_timeout)
+int wpa_ft_fetch_pmk_r1(struct wpa_authenticator *wpa_auth,
+                       const u8 *spa, const u8 *pmk_r1_name,
+                       u8 *pmk_r1, size_t *pmk_r1_len, int *pairwise,
+                       struct vlan_description *vlan,
+                       const u8 **identity, size_t *identity_len,
+                       const u8 **radius_cui, size_t *radius_cui_len,
+                       int *session_timeout)
 {
        struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
        struct wpa_ft_pmk_r1_sa *r1;