]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
PR: Store PMK length separately instead of using fixed length
authorJouni Malinen <jouni.malinen@oss.qualcomm.com>
Wed, 17 Dec 2025 10:55:37 +0000 (12:55 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 18 Dec 2025 10:08:24 +0000 (12:08 +0200)
PMK might be of variable length, so get rid of some more hardcoded
expectations regarding its length.

Signed-off-by: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
src/common/proximity_ranging.c
src/common/proximity_ranging.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/pr_supplicant.c
wpa_supplicant/pr_supplicant.h

index 13aa500b8ddbd053e14501c7d39af7407cf547d4..0a1f87ea77b88f8ab473b0e3e9d20f4ec48c0a2e 100644 (file)
@@ -185,7 +185,7 @@ void pr_clear_dev_iks(struct pr_data *pr)
 
 
 void pr_add_dev_ik(struct pr_data *pr, const u8 *dik, const char *password,
-                  const u8 *pmk, bool own)
+                  const u8 *pmk, size_t pmk_len, bool own)
 {
        struct pr_dev_ik *dev_ik;
 
@@ -200,6 +200,11 @@ void pr_add_dev_ik(struct pr_data *pr, const u8 *dik, const char *password,
                return;
        }
 
+       if (pmk && (pmk_len != 32 && pmk_len != 48 && pmk_len != 64)) {
+               wpa_printf(MSG_INFO, "PR: Unexpected PMK length %zu", pmk_len);
+               return;
+       }
+
        dl_list_for_each(dev_ik, &pr->dev_iks, struct pr_dev_ik, list) {
                if (os_memcmp(dik, dev_ik->dik, DEVICE_IDENTITY_KEY_LEN) == 0) {
                        dl_list_del(&dev_ik->list);
@@ -220,7 +225,8 @@ void pr_add_dev_ik(struct pr_data *pr, const u8 *dik, const char *password,
                dev_ik->password_valid = true;
        }
        if (pmk) {
-               os_memcpy(dev_ik->pmk, pmk, WPA_PASN_PMK_LEN);
+               os_memcpy(dev_ik->pmk, pmk, pmk_len);
+               dev_ik->pmk_len = pmk_len;
                dev_ik->pmk_valid = true;
        }
 
@@ -457,7 +463,8 @@ static int pr_validate_dira(struct pr_data *pr, struct pr_device *dev,
                        }
                        if (dev_ik->pmk_valid) {
                                os_memcpy(dev->pmk, dev_ik->pmk,
-                                         WPA_PASN_PMK_LEN);
+                                         dev_ik->pmk_len);
+                               dev->pmk_len = dev_ik->pmk_len;
                                dev->pmk_valid = true;
                        }
                        return 0;
@@ -1755,14 +1762,14 @@ static int pr_pasn_initialize(struct pr_data *pr, struct pr_device *dev,
                                                       pasn->own_addr,
                                                       pasn->peer_addr,
                                                       dev->pmk,
-                                                      WPA_PASN_PMK_LEN,
+                                                      dev->pmk_len,
                                                       pmkid);
                else
                        pasn_responder_pmksa_cache_add(pr->responder_pmksa,
                                                       pasn->own_addr,
                                                       pasn->peer_addr,
                                                       dev->pmk,
-                                                      WPA_PASN_PMK_LEN,
+                                                      dev->pmk_len,
                                                       pmkid);
                pasn->akmp = WPA_KEY_MGMT_SAE;
        } else {
index 284b5707ec220f4f8ff27f9db61ec0f53ab685a8..14106d2fbbe45323c2ab069e9f9e58305a0a91f6 100644 (file)
@@ -261,7 +261,8 @@ struct pr_dev_ik {
        u8 dik[DEVICE_IDENTITY_KEY_LEN];
        char password[100];
        bool password_valid;
-       u8 pmk[WPA_PASN_PMK_LEN];
+       u8 pmk[PMK_LEN_MAX];
+       size_t pmk_len;
        bool pmk_valid;
 };
 
@@ -292,6 +293,7 @@ struct pr_device {
         * This is updated with valid PMK if DIRA matches for the peer.
         */
        u8 pmk[PMK_LEN_MAX];
+       size_t pmk_len;
        bool pmk_valid;
 
 #ifdef CONFIG_PASN
@@ -489,7 +491,7 @@ void pr_deinit(struct pr_data *pr);
 void pr_set_dev_addr(struct pr_data *pr, const u8 *addr);
 void pr_clear_dev_iks(struct pr_data *pr);
 void pr_add_dev_ik(struct pr_data *pr, const u8 *dik, const char *password,
-                  const u8 *pmk, bool own);
+                  const u8 *pmk, size_t pmk_len, bool own);
 struct wpabuf * pr_prepare_usd_elems(struct pr_data *pr);
 void pr_process_usd_elems(struct pr_data *pr, const u8 *ies, u16 ies_len,
                          const u8 *peer_addr, unsigned int freq);
index 2b7ffe8690dd6271a7755eb76bbe7604bfcf4675..729e16ac144647eeb42407786f18077941ab2909 100644 (file)
@@ -11567,6 +11567,7 @@ static int wpas_ctrl_iface_pr_set_dik_ctx(struct wpa_supplicant *wpa_s,
        const char *password = NULL;
        const u8 *pmk = NULL, *dik = NULL;
        struct wpabuf *pmk_buf = NULL, *dik_buf = NULL;
+       size_t pmk_len;
 
        while ((token = str_token(cmd, " ", &context))) {
                if (os_strcmp(token, "self") == 0) {
@@ -11592,6 +11593,7 @@ static int wpas_ctrl_iface_pr_set_dik_ctx(struct wpa_supplicant *wpa_s,
                        if (!pmk_buf)
                                goto fail;
                        pmk = wpabuf_head_u8(pmk_buf);
+                       pmk_len = wpabuf_len(pmk_buf);
                        continue;
                }
        }
@@ -11599,7 +11601,7 @@ static int wpas_ctrl_iface_pr_set_dik_ctx(struct wpa_supplicant *wpa_s,
        if (!dik)
                goto fail;
 
-       wpas_pr_set_dev_ik(wpa_s, dik, password, pmk, own);
+       wpas_pr_set_dev_ik(wpa_s, dik, password, pmk, pmk_len, own);
        ret = 0;
 fail:
        wpabuf_clear_free(dik_buf);
index 5b9591be7e749e1b0849679f9a27cf3ab394e860..79c35e5c3548912ed5b5f34ff0a7666416562038 100644 (file)
@@ -473,14 +473,15 @@ void wpas_pr_clear_dev_iks(struct wpa_supplicant *wpa_s)
 
 
 void wpas_pr_set_dev_ik(struct wpa_supplicant *wpa_s, const u8 *dik,
-                       const char *password, const u8 *pmk, bool own)
+                       const char *password, const u8 *pmk, size_t pmk_len,
+                       bool own)
 {
        struct pr_data *pr = wpa_s->global->pr;
 
        if (!pr || !dik)
                return;
 
-       pr_add_dev_ik(pr, dik, password, pmk, own);
+       pr_add_dev_ik(pr, dik, password, pmk, pmk_len, own);
 }
 
 
index f5bc52570838430077a4c7955fdb9931efcbb19f..24c369e30b3f95a3e98ec3d9588aa6282153a558 100644 (file)
@@ -18,7 +18,8 @@ void wpas_pr_deinit(struct wpa_supplicant *wpa_s);
 void wpas_pr_update_dev_addr(struct wpa_supplicant *wpa_s);
 void wpas_pr_clear_dev_iks(struct wpa_supplicant *wpa_s);
 void wpas_pr_set_dev_ik(struct wpa_supplicant *wpa_s, const u8 *dik,
-                       const char *password, const u8 *pmk, bool own);
+                       const char *password, const u8 *pmk, size_t pmk_len,
+                       bool own);
 struct wpabuf * wpas_pr_usd_elems(struct wpa_supplicant *wpa_s);
 void wpas_pr_process_usd_elems(struct wpa_supplicant *wpa_s, const u8 *buf,
                               u16 buf_len, const u8 *peer_addr,
@@ -60,7 +61,7 @@ static inline void wpas_pr_clear_dev_iks(struct wpa_supplicant *wpa_s)
 
 static inline void wpas_pr_set_dev_ik(struct wpa_supplicant *wpa_s,
                                      const u8 *dik, const char *password,
-                                     const u8 *pmk, bool own)
+                                     const u8 *pmk, size_t pmk_len, bool own)
 {
 }