From: Jouni Malinen Date: Wed, 17 Dec 2025 10:55:37 +0000 (+0200) Subject: PR: Store PMK length separately instead of using fixed length X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e80d71240796fc9682be516ea6c86f22a7b9681c;p=thirdparty%2Fhostap.git PR: Store PMK length separately instead of using fixed length PMK might be of variable length, so get rid of some more hardcoded expectations regarding its length. Signed-off-by: Jouni Malinen --- diff --git a/src/common/proximity_ranging.c b/src/common/proximity_ranging.c index 13aa500b8..0a1f87ea7 100644 --- a/src/common/proximity_ranging.c +++ b/src/common/proximity_ranging.c @@ -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 { diff --git a/src/common/proximity_ranging.h b/src/common/proximity_ranging.h index 284b5707e..14106d2fb 100644 --- a/src/common/proximity_ranging.h +++ b/src/common/proximity_ranging.h @@ -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); diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 2b7ffe869..729e16ac1 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -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); diff --git a/wpa_supplicant/pr_supplicant.c b/wpa_supplicant/pr_supplicant.c index 5b9591be7..79c35e5c3 100644 --- a/wpa_supplicant/pr_supplicant.c +++ b/wpa_supplicant/pr_supplicant.c @@ -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); } diff --git a/wpa_supplicant/pr_supplicant.h b/wpa_supplicant/pr_supplicant.h index f5bc52570..24c369e30 100644 --- a/wpa_supplicant/pr_supplicant.h +++ b/wpa_supplicant/pr_supplicant.h @@ -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) { }