]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
PASN: Allow custom PMKID in Authentication frames for Wi-Fi Aware
authorVinay Gannevaram <quic_vganneva@quicinc.com>
Fri, 7 Oct 2022 14:06:35 +0000 (19:36 +0530)
committerJouni Malinen <j@w1.fi>
Thu, 3 Nov 2022 22:52:17 +0000 (00:52 +0200)
Wi-Fi Aware R4 specification introduces a custom PMKID derived from
Nonce and TAG. This custom PMKID is included in PASN Authentication
frames during pairing verification. So, allow use of a custom PMKID in
PASN frames and validate it using a function handler. Wi-Fi Aware
component that uses libpasn.so should take care of validating the custom
PMKID.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
src/ap/ieee802_11.c
src/pasn/pasn_common.h
wpa_supplicant/pasn_supplicant.c

index 14e4a4eabb58c1c470549f098d4b2d47ca8fc336..810fc9ebd41a45b22457d4c3c286162e7686434c 100644 (file)
@@ -3088,7 +3088,9 @@ static int handle_auth_pasn_resp(struct wpas_pasn *pasn, const u8 *own_addr,
        if (status != WLAN_STATUS_SUCCESS)
                goto done;
 
-       if (pmksa) {
+       if (pmksa && pasn->custom_pmkid_valid)
+               pmkid = pasn->custom_pmkid;
+       else if (pmksa) {
                pmkid = pmksa->pmkid;
 #ifdef CONFIG_SAE
        } else if (pasn->akmp == WPA_KEY_MGMT_SAE) {
@@ -3525,9 +3527,25 @@ static int handle_auth_pasn_1(struct wpas_pasn *pasn,
                        wpa_printf(MSG_DEBUG, "PASN: Try to find PMKSA entry");
 
                        if (pasn->pmksa) {
+                               const u8 *pmkid = NULL;
+
+                               if (pasn->custom_pmkid_valid) {
+                                       ret = pasn->validate_custom_pmkid(
+                                               pasn->cb_ctx, peer_addr,
+                                               rsn_data.pmkid);
+                                       if (ret) {
+                                               wpa_printf(MSG_DEBUG,
+                                                          "PASN: Failed custom PMKID validation");
+                                               status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+                                               goto send_resp;
+                                       }
+                               } else {
+                                       pmkid = rsn_data.pmkid;
+                               }
+
                                pmksa = pmksa_cache_auth_get(pasn->pmksa,
                                                             peer_addr,
-                                                            rsn_data.pmkid);
+                                                            pmkid);
                                if (pmksa) {
                                        cached_pmk = pmksa->pmk;
                                        cached_pmk_len = pmksa->pmk_len;
index 24e3b5a9921645869762b46416e0ce0406f0dc30..f95df2b1bb09992753bdafae9ddaf4c6f03c4e04 100644 (file)
@@ -112,6 +112,9 @@ struct wpas_pasn {
        u16 comeback_idx;
        u16 *comeback_pending_idx;
 
+       bool custom_pmkid_valid;
+       u8 custom_pmkid[PMKID_LEN];
+
        /**
         * send_mgmt - Function handler to transmit a Management frame
         * @ctx: Callback context from cb_ctx
@@ -123,6 +126,15 @@ struct wpas_pasn {
         */
        int (*send_mgmt)(void *ctx, const u8 *data, size_t data_len, int noack,
                         unsigned int freq, unsigned int wait);
+       /**
+        * validate_custom_pmkid - Handler to validate vendor specific PMKID
+        * @ctx: Callback context from cb_ctx
+        * @addr : MAC address of the peer
+        * @pmkid: Custom PMKID
+        * Returns: 0 on success (valid PMKID), -1 on failure
+        */
+       int (*validate_custom_pmkid)(void *ctx, const u8 *addr,
+                                    const u8 *pmkid);
 };
 
 #endif /* CONFIG_PASN */
index 2650fd31f6db84b925a9076606e0dbcbcfb071a5..353e4ae9dc99eef75a3c6e769690a074426007a8 100644 (file)
@@ -966,7 +966,9 @@ static struct wpabuf * wpas_pasn_build_auth_1(struct wpas_pasn *pasn,
 
                pmksa = pmksa_cache_get(pasn->pmksa, pasn->bssid,
                                        NULL, NULL, pasn->akmp);
-               if (pmksa)
+               if (pmksa && pasn->custom_pmkid_valid)
+                       pmkid = pasn->custom_pmkid;
+               else if (pmksa)
                        pmkid = pmksa->pmkid;
 
                /*
@@ -1147,6 +1149,7 @@ static void wpa_pasn_reset(struct wpas_pasn *pasn)
        pasn->rsn_ie = NULL;
        pasn->rsn_ie_len = 0;
        pasn->rsnxe_ie = NULL;
+       pasn->custom_pmkid_valid = false;
 }
 
 
@@ -1195,10 +1198,25 @@ static int wpas_pasn_set_pmk(struct wpas_pasn *pasn,
        }
 
        if (rsn_data->num_pmkid) {
+               int ret;
                struct rsn_pmksa_cache_entry *pmksa;
+               const u8 *pmkid = NULL;
+
+               if (pasn->custom_pmkid_valid) {
+                       ret = pasn->validate_custom_pmkid(pasn->cb_ctx,
+                                                         pasn->bssid,
+                                                         rsn_data->pmkid);
+                       if (ret) {
+                               wpa_printf(MSG_DEBUG,
+                                          "PASN: Failed custom PMKID validation");
+                               return -1;
+                       }
+               } else {
+                       pmkid = rsn_data->pmkid;
+               }
 
                pmksa = pmksa_cache_get(pasn->pmksa, pasn->bssid,
-                                       rsn_data->pmkid, NULL, pasn->akmp);
+                                       pmkid, NULL, pasn->akmp);
                if (pmksa) {
                        wpa_printf(MSG_DEBUG, "PASN: Using PMKSA");