Browse Source

OWE: PMKSA caching in station mode

This extends OWE support in wpa_supplicant to allow PMKSA caching to be
used.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Jouni Malinen 7 years ago
parent
commit
5a78c36194
3 changed files with 29 additions and 10 deletions
  1. 23 5
      src/rsn_supp/wpa.c
  2. 2 2
      src/rsn_supp/wpa.h
  3. 4 3
      wpa_supplicant/events.c

+ 23 - 5
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;
 }

+ 2 - 2
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);

+ 4 - 3
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;
 	}