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)
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) {
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
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 };
}
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;
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);
}
-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;