Address review comments VNC

This commit is contained in:
Akshat Agrawal
2026-06-30 14:56:35 +08:00
committed by Jack
parent ff5df2e245
commit 7475e1bced
9 changed files with 108 additions and 56 deletions
@@ -232,6 +232,9 @@ struct nan_secure_dp_funcs {
* encrypted KDE payload (GTK/IGTK/BIGTK). */
int (*ndp_security_install_get_shared_desc_len)(void);
uint8_t (*get_ndp_resp_num_pmkids)(uint8_t ndp_id, const uint8_t *peer_nmi);
uint32_t (*get_ndp_resp_shared_key_desc_len)(uint8_t ndp_id, const uint8_t *peer_nmi);
/* --- CSIA / SCIA construction. Each writes a complete NAN
* attribute (header + body) at @c frm and returns bytes
* written, or -1 on error. --- */
@@ -1669,9 +1669,6 @@ typedef struct {
uint32_t cookie; /**< Comeback cookie from responder (0 if none) */
} wifi_event_nan_bootstrap_complete_t;
#define WIFI_NAN_PAIRING_REASON_NIK_FUP_TIMEOUT 1 /**< Local reason: peer NIK follow-up not received within timeout.
See Wi-Fi Aware v4.0 §7.6.4.2 for the NIK-exchange procedure. */
/**
* @brief Argument structure for WIFI_EVENT_NAN_PAIRING_CONFIRM event
*/
@@ -1669,9 +1669,6 @@ typedef struct {
uint32_t cookie; /**< Comeback cookie from responder (0 if none) */
} wifi_event_nan_bootstrap_complete_t;
#define WIFI_NAN_PAIRING_REASON_NIK_FUP_TIMEOUT 1 /**< Local reason: peer NIK follow-up not received within timeout.
See Wi-Fi Aware v4.0 §7.6.4.2 for the NIK-exchange procedure. */
/**
* @brief Argument structure for WIFI_EVENT_NAN_PAIRING_CONFIRM event
*/
@@ -53,6 +53,9 @@ void esp_nan_action_stop(void);
#ifdef CONFIG_ESP_WIFI_NAN_PAIRING
#define WIFI_NAN_PAIRING_REASON_NIK_FUP_TIMEOUT 1 /**< Local reason: peer NIK follow-up not received within timeout.
See Wi-Fi Aware v4.0 §7.6.4.2 for the NIK-exchange procedure. */
#ifndef NAN_PAIRING_PINCODE_MIN
#define NAN_PAIRING_PINCODE_MIN 0
#endif
@@ -1375,6 +1375,8 @@ static struct nan_secure_dp_funcs s_nan_secure_dp_funcs = {
.get_scia_len = esp_nan_get_scia_len,
.get_shared_key_desc_attr_len = esp_nan_get_shared_key_desc_attr_len,
.ndp_security_install_get_shared_desc_len = esp_nan_ndp_security_install_get_shared_desc_len,
.get_ndp_resp_num_pmkids = esp_nan_get_ndp_resp_num_pmkids,
.get_ndp_resp_shared_key_desc_len = esp_nan_get_ndp_resp_shared_key_desc_len,
/* CSIA / SCIA construction */
.construct_csia = esp_nan_construct_csia,
@@ -366,6 +366,8 @@ uint32_t esp_nan_get_csia_len(uint16_t own_csid_bitmap, uint16_t peer_csid_bitma
uint32_t esp_nan_get_scia_len(uint8_t num_pmkids);
uint32_t esp_nan_get_shared_key_desc_attr_len(uint16_t key_data_len);
int esp_nan_ndp_security_install_get_shared_desc_len(void);
uint8_t esp_nan_get_ndp_resp_num_pmkids(uint8_t ndp_id, const uint8_t *peer_nmi);
uint32_t esp_nan_get_ndp_resp_shared_key_desc_len(uint8_t ndp_id, const uint8_t *peer_nmi);
int esp_nan_construct_csia(uint8_t *frm, uint8_t pub_id,
uint16_t own_csid_bitmap, uint16_t peer_csid_bitmap);
@@ -510,7 +510,9 @@ static void nan_pairing_nik_fup_timeout_cb(void *eloop_data, void *user_ctx)
#if defined(CONFIG_ESP_WIFI_NAN_SECURITY)
nan_app_remove_paired_peer(own->nik_fup_pending_peer_nmi);
#endif
esp_nan_complete_pairing(own->svc_id);
struct peer_svc_info *peer = nan_find_peer_svc(own->svc_id, 0,
own->nik_fup_pending_peer_nmi);
esp_nan_complete_pairing(own->svc_id, peer ? peer->svc_id : 0);
nan_app_post_event(WIFI_EVENT_NAN_PAIRING_CONFIRM, &evt, sizeof(evt));
ESP_LOGW(TAG, "Pairing succeeded but NIK caching timed out for peer " MACSTR
" (reason=%u)", MAC2STR(own->nik_fup_pending_peer_nmi), evt.reason_code);
@@ -811,7 +813,7 @@ static void nan_pairing_key_installed_cb(const uint8_t *peer_nmi,
evt.status = WIFI_NAN_PAIRING_STATUS_ACCEPTED;
evt.reason_code = 0;
MACADDR_COPY(evt.peer_nmi, peer_nmi);
esp_nan_complete_pairing(own->svc_id);
esp_nan_complete_pairing(own->svc_id, peer->svc_id);
nan_app_post_event(WIFI_EVENT_NAN_PAIRING_CONFIRM, &evt, sizeof(evt));
return;
}
@@ -998,7 +1000,8 @@ void nan_app_receive_pairing_followup(uint8_t svc_id, uint8_t peer_svc_id,
evt.status = WIFI_NAN_PAIRING_STATUS_ACCEPTED;
evt.reason_code = 0;
MACADDR_COPY(evt.peer_nmi, peer_mac);
esp_nan_complete_pairing(p_peer_svc ? p_peer_svc->own_svc_id : 0);
esp_nan_complete_pairing(p_peer_svc ? p_peer_svc->own_svc_id : 0,
p_peer_svc ? p_peer_svc->svc_id : peer_svc_id);
nan_app_post_event(WIFI_EVENT_NAN_PAIRING_CONFIRM, &evt, sizeof(evt));
}
@@ -427,6 +427,91 @@ static bool nan_security_fill_from_paired_cache(struct ndl_info *ndl, const uint
}
#endif
static bool nan_ndp_resp_resolve_pmk(struct ndl_info *ndl, const uint8_t *peer_nmi)
{
static const uint8_t zero_pmkid[ESP_WIFI_NAN_NDP_PMKID_LEN] = {0};
static const uint8_t zero_pmk[ESP_WIFI_NAN_NDP_PMK_LEN] = {0};
if (!ndl || !peer_nmi) {
return false;
}
bool have_peer_pmkid = (memcmp(ndl->security_ctx.nd_pmkid, zero_pmkid,
ESP_WIFI_NAN_NDP_PMKID_LEN) != 0);
bool need_pmk = (ndl->security_ctx.type != WIFI_NAN_SECURITY_ENCRYPTED) ||
(memcmp(ndl->security_ctx.nd_pmk, zero_pmk, ESP_WIFI_NAN_NDP_PMK_LEN) == 0);
if (!need_pmk) {
return have_peer_pmkid;
}
#if defined(CONFIG_ESP_WIFI_NAN_PAIRING)
if (nan_security_fill_from_paired_cache(ndl, peer_nmi)) {
return have_peer_pmkid;
}
#endif
if (!have_peer_pmkid) {
return false;
}
struct own_svc_info *p_svc = nan_find_own_svc(ndl->publisher_id);
int matched_idx = p_svc ? nan_match_pmkid(p_svc, ndl->security_ctx.nd_pmkid,
ndl->peer_nmi, ndl->peer_ndi) : -1;
if (matched_idx < 0) {
return false;
}
ndl->security_ctx.type = WIFI_NAN_SECURITY_ENCRYPTED;
ndl->security_ctx.csid_bitmap = p_svc->derived_security[matched_idx].csid_bitmap;
memcpy(ndl->security_ctx.nd_pmk,
p_svc->derived_security[matched_idx].nd_pmk,
ESP_WIFI_NAN_NDP_PMK_LEN);
return true;
}
uint8_t esp_nan_get_ndp_resp_num_pmkids(uint8_t ndp_id, const uint8_t *peer_nmi)
{
static const uint8_t zero_pmkid[ESP_WIFI_NAN_NDP_PMKID_LEN] = {0};
if (!peer_nmi) {
return 0;
}
NAN_DATA_LOCK();
struct ndl_info *ndl = nan_find_ndl(ndp_id, (uint8_t *)peer_nmi);
if (!ndl) {
ndl = nan_find_ndl(0, (uint8_t *)peer_nmi);
}
uint8_t num = 0;
if (ndl && memcmp(ndl->security_ctx.nd_pmkid, zero_pmkid, ESP_WIFI_NAN_NDP_PMKID_LEN) != 0) {
num = 1;
}
NAN_DATA_UNLOCK();
return num;
}
uint32_t esp_nan_get_ndp_resp_shared_key_desc_len(uint8_t ndp_id, const uint8_t *peer_nmi)
{
if (!peer_nmi) {
return 0;
}
NAN_DATA_LOCK();
struct ndl_info *ndl = nan_find_ndl(ndp_id, (uint8_t *)peer_nmi);
if (!ndl) {
ndl = nan_find_ndl(0, (uint8_t *)peer_nmi);
}
if (!ndl || ndl->handshake_state != NAN_HANDSHAKE_M1_RCVD ||
!nan_ndp_resp_resolve_pmk(ndl, peer_nmi)) {
NAN_DATA_UNLOCK();
return 0;
}
NAN_DATA_UNLOCK();
return esp_nan_get_shared_key_desc_attr_len(0);
}
/*
* Build RSNA Key Descriptor payload (95-byte EAPOL-Key layout, see
* IEEE 802.11-2020 §12.7.2). NAN carries this body inside the NAN
@@ -1134,9 +1219,9 @@ int esp_nan_ndp_security_install_get_shared_desc_len(void)
int esp_nan_get_ndp_resp_shared_key_desc(uint8_t *buf, size_t buf_len, uint8_t ndp_id, const uint8_t *peer_nmi)
{
const uint32_t attr_len = esp_nan_get_shared_key_desc_attr_len(0);
const uint32_t attr_len = esp_nan_get_ndp_resp_shared_key_desc_len(ndp_id, peer_nmi);
if (!buf || buf_len < attr_len || !peer_nmi) {
if (!buf || !peer_nmi || attr_len == 0 || buf_len < attr_len) {
return 0;
}
@@ -1152,50 +1237,10 @@ int esp_nan_get_ndp_resp_shared_key_desc(uint8_t *buf, size_t buf_len, uint8_t n
ESP_LOGW(TAG, "NDP Resp Key Desc: NDL not in M1_RCVD (state=%d)", ndl->handshake_state);
return 0;
}
/* Resolve PMK from publish when: NDL not encrypted, or encrypted but nd_pmk not set */
{
static const uint8_t zero_pmkid[ESP_WIFI_NAN_NDP_PMKID_LEN] = {0};
static const uint8_t zero_pmk[ESP_WIFI_NAN_NDP_PMK_LEN] = {0};
bool have_peer_pmkid = (memcmp(ndl->security_ctx.nd_pmkid, zero_pmkid,
ESP_WIFI_NAN_NDP_PMKID_LEN) != 0);
bool need_pmk = (ndl->security_ctx.type != WIFI_NAN_SECURITY_ENCRYPTED) ||
(memcmp(ndl->security_ctx.nd_pmk, zero_pmk, ESP_WIFI_NAN_NDP_PMK_LEN) == 0);
bool resolved_from_pairing_cache = false;
#if defined(CONFIG_ESP_WIFI_NAN_PAIRING)
if (need_pmk) {
resolved_from_pairing_cache = nan_security_fill_from_paired_cache(ndl, peer_nmi);
}
#endif
if (resolved_from_pairing_cache) {
ESP_LOGD(TAG, "NDP Resp Key Desc: resolved PMK from paired-peer cache");
} else if (need_pmk && have_peer_pmkid) {
struct own_svc_info *p_svc = nan_find_own_svc(ndl->publisher_id);
int matched_idx = p_svc ? nan_match_pmkid(p_svc, ndl->security_ctx.nd_pmkid,
ndl->peer_nmi, ndl->peer_ndi) : -1;
if (matched_idx >= 0) {
ndl->security_ctx.type = WIFI_NAN_SECURITY_ENCRYPTED;
ndl->security_ctx.csid_bitmap = p_svc->derived_security[matched_idx].csid_bitmap;
memcpy(ndl->security_ctx.nd_pmk,
p_svc->derived_security[matched_idx].nd_pmk,
ESP_WIFI_NAN_NDP_PMK_LEN);
ESP_LOGD(TAG, "NDP Resp Key Desc: resolved PMK from cred slot %d", matched_idx);
} else if (ndl->security_ctx.type != WIFI_NAN_SECURITY_ENCRYPTED) {
NAN_DATA_UNLOCK();
ESP_LOGW(TAG, "NDP Resp Key Desc: NDL not encrypted; send NDP Response without Shared Key Descriptor");
return 0;
} else {
NAN_DATA_UNLOCK();
ESP_LOGW(TAG, "NDP Resp Key Desc: no PMK for peer PMKID; ensure matching credential on both devices");
return 0;
}
} else if (ndl->security_ctx.type != WIFI_NAN_SECURITY_ENCRYPTED) {
NAN_DATA_UNLOCK();
ESP_LOGW(TAG, "NDP Resp Key Desc: NDL not encrypted; send NDP Response without Shared Key Descriptor");
return 0;
}
if (!nan_ndp_resp_resolve_pmk(ndl, peer_nmi)) {
NAN_DATA_UNLOCK();
ESP_LOGW(TAG, "NDP Resp Key Desc: no PMK for peer PMKID; ensure matching credential on both devices");
return 0;
}
/* Generate SNonce and derive PTK if not yet done */
@@ -341,7 +341,7 @@ void esp_wifi_ap_set_group_mgmt_cipher_internal(wifi_cipher_type_t cipher);
uint8_t esp_wifi_op_class_supported_internal(uint8_t op_class, uint8_t min_chan, uint8_t max_chan, uint8_t inc, uint8_t bw, channel_bitmap_t *non_pref_channels);
bool esp_wifi_is_wpa3_compatible_mode_enabled(uint8_t if_index);
uint8_t esp_wifi_ap_get_owe_config_internal(void);
esp_err_t esp_nan_complete_pairing(uint8_t svc_id);
esp_err_t esp_nan_complete_pairing(uint8_t svc_id, uint8_t peer_svc_id);
esp_err_t esp_wifi_nan_load_saved_creds(uint8_t own_nik[ESP_WIFI_NAN_NIK_LEN], bool *own_nik_valid,
wifi_nan_peer_creds_t peer_creds[ESP_WIFI_NAN_MAX_PEER_CREDS], uint8_t *num_peer_creds);
esp_err_t esp_wifi_nan_save_own_nik(const uint8_t own_nik[ESP_WIFI_NAN_NIK_LEN]);