diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index d29565f9b..0e9f05d3e 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -4215,8 +4215,8 @@ fail: } -int owe_process_assoc_resp(struct wpa_sm *sm, const u8 *resp_ies, - size_t resp_ies_len) +int owe_process_assoc_resp(struct wpa_sm *sm, const u8 *bssid, + const u8 *resp_ies, size_t resp_ies_len) { struct ieee802_11_elems elems; u16 group; @@ -4227,11 +4227,27 @@ int owe_process_assoc_resp(struct wpa_sm *sm, const u8 *resp_ies, const u8 *addr[2]; size_t len[2]; size_t hash_len, prime_len; + struct wpa_ie_data data; if (!resp_ies || ieee802_11_parse_elems(resp_ies, resp_ies_len, &elems, 1) == - ParseFailed || - !elems.owe_dh) { + ParseFailed) { + wpa_printf(MSG_INFO, + "OWE: Could not parse Association Response frame elements"); + return -1; + } + + if (sm->cur_pmksa && elems.rsn_ie && + wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, 2 + elems.rsn_ie_len, + &data) == 0 && + data.num_pmkid == 1 && data.pmkid && + os_memcmp(sm->cur_pmksa->pmkid, data.pmkid, PMKID_LEN) == 0) { + wpa_printf(MSG_DEBUG, "OWE: Use PMKSA caching"); + wpa_sm_set_pmk_from_pmksa(sm); + return 0; + } + + if (!elems.owe_dh) { wpa_printf(MSG_INFO, "OWE: No Diffie-Hellman Parameter element found in Association Response frame"); return -1; @@ -4347,7 +4363,9 @@ int owe_process_assoc_resp(struct wpa_sm *sm, const u8 *resp_ies, wpa_hexdump_key(MSG_DEBUG, "OWE: PMK", sm->pmk, sm->pmk_len); wpa_hexdump(MSG_DEBUG, "OWE: PMKID", pmkid, PMKID_LEN); - /* TODO: Add PMKSA cache entry */ + pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, pmkid, NULL, 0, + bssid, sm->own_addr, sm->network_ctx, sm->key_mgmt, + NULL); return 0; } diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index e7d1b7876..805de633a 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -458,8 +458,8 @@ struct wpabuf * fils_build_assoc_req(struct wpa_sm *sm, const u8 **kek, int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len); struct wpabuf * owe_build_assoc_req(struct wpa_sm *sm, u16 group); -int owe_process_assoc_resp(struct wpa_sm *sm, const u8 *resp_ies, - size_t resp_ies_len); +int owe_process_assoc_resp(struct wpa_sm *sm, const u8 *bssid, + const u8 *resp_ies, size_t resp_ies_len); void wpa_sm_set_reset_fils_completed(struct wpa_sm *sm, int set); void wpa_sm_set_fils_cache_id(struct wpa_sm *sm, const u8 *fils_cache_id); diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 65d453c3c..f0b78e9ec 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -2336,9 +2336,10 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, #ifdef CONFIG_OWE if (wpa_s->key_mgmt == WPA_KEY_MGMT_OWE && - owe_process_assoc_resp(wpa_s->wpa, - data->assoc_info.resp_ies, - data->assoc_info.resp_ies_len) < 0) { + (wpa_drv_get_bssid(wpa_s, bssid) < 0 || + owe_process_assoc_resp(wpa_s->wpa, bssid, + data->assoc_info.resp_ies, + data->assoc_info.resp_ies_len) < 0)) { wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_UNSPECIFIED); return -1; }