Fix(NAN): fix Memory Corruption due to BIP encryption

- Set internal NAN params based on the user configurable Platform

 - On a secured NDP the responder could not derive keys
   (passphrase/credential mismatch); reject cleanly and
   fire ndp_terminated/ndp_confirm(REJECTED) on every
   teardown path so the host frees the NDP-ID.

 - Tear down the old NDP when the same peer re-initiates with
   a new M1, instead of rejecting and leaking the NDL.
This commit is contained in:
Akshat Agrawal
2026-07-17 13:51:16 +05:30
parent a8ff7d2ab3
commit 4f93a6777b
4 changed files with 57 additions and 2 deletions
@@ -49,6 +49,26 @@ void esp_nan_action_start(esp_netif_t *nan_netif);
*/
void esp_nan_action_stop(void);
/**
* @brief NAN peer-platform compatibility mode
*/
typedef enum {
NAN_COMPATIBILITY_MODE_DEFAULT = 0, /**< Default compatibility mode for Wi-Fi Aware peers */
NAN_COMPATIBILITY_MODE_IOS, /**< Interoperate with iOS Wi-Fi Aware peers */
NAN_COMPATIBILITY_MODE_ANDROID, /**< Interoperate with Android Wi-Fi Aware peers */
} nan_compatibility_mode_t;
/**
* @brief Set NAN peer-platform compatibility mode
*
* @param mode Compatibility mode to target for discovery/SSI framing.
*
* @return
* - ESP_OK: succeed
* - ESP_FAIL: Invalid compatibility mode
*/
esp_err_t esp_nan_set_compatibility_mode_internal(nan_compatibility_mode_t mode);
#endif /* CONFIG_ESP_WIFI_NAN_SYNC_ENABLE */
#ifdef CONFIG_ESP_WIFI_NAN_PAIRING
@@ -61,6 +61,8 @@ bool esp_nan_verify_nira_get_own_svc(uint8_t *peer_mac, uint8_t *nira_attr,
#if defined(CONFIG_ESP_WIFI_NAN_SYNC_ENABLE) && defined(CONFIG_ESP_WIFI_PASN_SUPPORT)
#include "esp_private/esp_supp_nan.h"
#include "apps_private/wifi_apps_private.h"
#elif defined(CONFIG_ESP_WIFI_NAN_SYNC_ENABLE)
#include "apps_private/wifi_apps_private.h"
#endif
/* NAN States */
@@ -1891,6 +1893,34 @@ void esp_nan_action_stop(void)
os_event_group_set_bits(nan_event_group, NAN_STOPPED_BIT);
}
static int nan_set_params_ipc(void *arg)
{
wifi_nan_compat_params_t *params = arg;
return esp_wifi_nan_set_params_internal(*params);
}
esp_err_t esp_nan_set_compatibility_mode_internal(nan_compatibility_mode_t mode)
{
wifi_ipc_config_t cfg;
wifi_nan_compat_params_t params = {0};
if (mode > NAN_COMPATIBILITY_MODE_ANDROID) {
ESP_LOGE(TAG, "Invalid compatibility mode");
return ESP_ERR_INVALID_ARG;
}
if (mode == NAN_COMPATIBILITY_MODE_ANDROID) {
params.nan_gsp_in_sda = 1;
}
cfg.fn = nan_set_params_ipc;
cfg.arg = &params;
cfg.arg_size = sizeof(params);
return esp_wifi_ipc_internal(&cfg, false);
}
esp_err_t esp_wifi_nan_sync_start(const wifi_nan_sync_config_t *nan_cfg)
{
wifi_mode_t mode;
@@ -249,6 +249,11 @@ typedef struct {
bool is_valid; /**< True if this credential entry is valid */
} wifi_nan_peer_creds_t;
typedef struct {
uint8_t nan_gsp_in_sda : 1; /**< Include GSP in SDA for Android peer compatibility */
uint8_t reserved : 7;
} wifi_nan_compat_params_t;
typedef wifi_scan_channel_bitmap_t channel_bitmap_t;
uint8_t *esp_wifi_ap_get_prof_pmk_internal(void);
@@ -354,5 +359,5 @@ esp_err_t esp_wifi_nan_save_own_nik(const uint8_t own_nik[ESP_WIFI_NAN_NIK_LEN])
esp_err_t esp_wifi_nan_save_creds_for_peer(const uint8_t peer_nik[ESP_WIFI_NAN_NIK_LEN],
const uint8_t npk[ESP_WIFI_NAN_NPK_LEN], const uint8_t service_hash[6]);
esp_err_t esp_wifi_nan_erase_all_creds(void);
esp_err_t esp_wifi_nan_set_params_internal(wifi_nan_compat_params_t params);
#endif /* _ESP_WIFI_DRIVER_H_ */