This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 11c1b68e21d6399076167d62cb6b8c68078051e3
Author: Jorge Guzman <[email protected]>
AuthorDate: Thu Jul 16 14:37:50 2026 -0300

    risc-v/gd32vw55x: reject WPA3/SAE networks instead of crashing
    
    Associating to a WPA3 (SAE) network faulted inside the prebuilt vendor
    supplicant (load access fault in the elliptic-curve math of the SAE
    handshake, wifi_mgmt task). The port is WPA2-only, so refuse what the
    supplicant cannot complete:
    
    - Undefine CONFIG_WPA3_SAE in the build_config.h shim. This activates
      the vendor's own fallback in wifi_netlink.c: the SAE/OWE AKMs are
      stripped from the connection config and the SAE auth algorithm is
      never selected, so a WPA3-transition AP (WPA2/WPA3 mixed) now
      associates through WPA2-PSK. The flag only gates code, not struct
      layout, so the prebuilt libraries are unaffected.
    
    - Refuse an SAE/OWE/802.1X-only network up front in the connect path
      with ENOTSUP and a console message naming the unsupported AKM bitmap,
      instead of an obscure association failure.
    
    Validated on hardware (GD32VW553K-START), all three cases: a WPA2
    network still associates (four-way handshake, DHCP, ping); a
    WPA2/WPA3 transition hotspot ([RSN:WPA-PSK,SAE CCMP/CCMP][MFP])
    associates through WPA2-PSK, gets a lease and pings the gateway
    (it crashed before this change); and a WPA3-only hotspot is now
    refused with
    
      gdwifi: 'wpa3test' offers no supported AKM (bitmap 0x200): WPA3/SAE,
      OWE and 802.1X are not supported, WPA2-PSK only
    
    where it previously crashed.
    
    Assisted-by: Claude Opus 4.8
    Signed-off-by: Jorge Guzman <[email protected]>
---
 .../gd32vw55x/boards/gd32vw553k-start/index.rst    |  7 ++
 .../src/gd32vw55x/gdwifi/config/build_config.h     | 13 ++++
 arch/risc-v/src/gd32vw55x/gdwifi/gdwifi_netdev.c   | 75 ++++++++++++++++++++++
 3 files changed, 95 insertions(+)

diff --git 
a/Documentation/platforms/risc-v/gd32vw55x/boards/gd32vw553k-start/index.rst 
b/Documentation/platforms/risc-v/gd32vw55x/boards/gd32vw553k-start/index.rst
index a57c855e7ba..2e90d40f6c2 100644
--- a/Documentation/platforms/risc-v/gd32vw55x/boards/gd32vw553k-start/index.rst
+++ b/Documentation/platforms/risc-v/gd32vw55x/boards/gd32vw553k-start/index.rst
@@ -173,6 +173,13 @@ network tools::
    Use ``ifup wlan0``, not ``ifconfig wlan0 up``: ``ifconfig`` interprets its
    second argument as an IP address.
 
+.. note::
+   The station is WPA2-only. A WPA3-transition network (WPA2/WPA3 mixed
+   mode) associates through WPA2-PSK; a WPA3(SAE)-only network is refused
+   up front with ``ENOTSUP`` and a console message naming the unsupported
+   AKM, instead of letting the prebuilt supplicant attempt the SAE
+   handshake (which faults).
+
 The RTC and the SNTP client are enabled, so the clock can be set from the
 network::
 
diff --git a/arch/risc-v/src/gd32vw55x/gdwifi/config/build_config.h 
b/arch/risc-v/src/gd32vw55x/gdwifi/config/build_config.h
index c923b0f43f3..e8a4c7050ce 100644
--- a/arch/risc-v/src/gd32vw55x/gdwifi/config/build_config.h
+++ b/arch/risc-v/src/gd32vw55x/gdwifi/config/build_config.h
@@ -8,6 +8,19 @@
 
 #include_next "build_config.h"
 
+/* The port is WPA2-only: the SAE (WPA3) handshake faults inside the
+ * prebuilt supplicant (load access fault in the elliptic-curve math).
+ * Undefining CONFIG_WPA3_SAE activates the vendor's own fallback in
+ * wifi_netlink.c: the SAE/OWE AKMs are stripped from the connection
+ * config and the SAE auth algorithm is never selected, so a
+ * WPA3-transition AP associates through WPA2-PSK and an SAE-only AP is
+ * rejected by the AP instead of crashing the supplicant.  (The glue also
+ * refuses SAE-only networks up front with a clear error -- see
+ * gdwifi_netdev.c.)
+ */
+
+#undef CONFIG_WPA3_SAE
+
 #ifndef __LITTLE_ENDIAN
 #define __LITTLE_ENDIAN 1234
 #endif
diff --git a/arch/risc-v/src/gd32vw55x/gdwifi/gdwifi_netdev.c 
b/arch/risc-v/src/gd32vw55x/gdwifi/gdwifi_netdev.c
index 6c02639226a..a691712c8f5 100644
--- a/arch/risc-v/src/gd32vw55x/gdwifi/gdwifi_netdev.c
+++ b/arch/risc-v/src/gd32vw55x/gdwifi/gdwifi_netdev.c
@@ -57,6 +57,7 @@
 #include <stddef.h>
 #include <net/if_arp.h>
 #include <debug.h>
+#include <syslog.h>
 #include <netinet/in.h>
 
 #include <nuttx/kmalloc.h>
@@ -599,6 +600,74 @@ static int  g_mode = IW_MODE_INFRA;   /* INFRA = station, 
MASTER = softAP */
 #define GDWIFI_AUTH_WPA2  3   /* AUTH_MODE_WPA2 (SAE/WPA3 no AP estoura o 
crypto) */
 #define GDWIFI_AP_CHANNEL 11
 
+/****************************************************************************
+ * Name: gdwifi_target_supported
+ *
+ * Description:
+ *   The port is WPA2-only (the SAE handshake faults inside the prebuilt
+ *   supplicant), so refuse a network that offers no AKM we can complete --
+ *   WPA3(SAE)-only being the common case -- with a clear error instead of
+ *   letting the association fail obscurely.  A targeted blocking scan
+ *   fetches the AKM bitmap of the AP; if the network cannot be found the
+ *   decision is left to the vendor connect path (same behavior as today).
+ *
+ ****************************************************************************/
+
+static int gdwifi_target_supported(void)
+{
+  struct macif_scan_results *results;
+  size_t ssid_len = strlen(g_essid);
+  uint32_t supported = CO_BIT(MAC_AKM_NONE) | CO_BIT(MAC_AKM_PRE_RSN) |
+                       CO_BIT(MAC_AKM_PSK) | CO_BIT(MAC_AKM_PSK_SHA256);
+  int ret = OK;
+  uint32_t i;
+
+  if (wifi_management_scan(1, g_essid) != 0)
+    {
+      return OK;
+    }
+
+  results = sys_malloc(sizeof(*results));
+  if (results == NULL)
+    {
+      return -ENOMEM;
+    }
+
+  if (wifi_netlink_scan_results_get(GDWIFI_VIF_STA, results) != 0)
+    {
+      sys_mfree(results);
+      return OK;
+    }
+
+  for (i = 0; i < results->result_cnt; i++)
+    {
+      struct mac_scan_result *ap = &results->result[i];
+
+      if (!ap->valid_flag || ap->ssid.length != ssid_len ||
+          memcmp(ap->ssid.array, g_essid, ssid_len) != 0)
+        {
+          continue;
+        }
+
+      if ((ap->akm & supported) == 0)
+        {
+          /* syslog, not nerr: the rejection must be visible in release
+           * configs too, or the refused connect looks like a silent no-op.
+           */
+
+          syslog(LOG_ERR, "gdwifi: '%s' offers no supported AKM (bitmap "
+                 "0x%lx): WPA3/SAE, OWE and 802.1X are not supported, "
+                 "WPA2-PSK only\n", g_essid, (unsigned long)ap->akm);
+          ret = -ENOTSUP;
+        }
+
+      break;
+    }
+
+  sys_mfree(results);
+  return ret;
+}
+
 static int gdwifi_connect(struct netdev_lowerhalf_s *dev)
 {
   int ret;
@@ -623,6 +692,12 @@ static int gdwifi_connect(struct netdev_lowerhalf_s *dev)
       return ret == 0 ? OK : -EAGAIN;
     }
 
+  ret = gdwifi_target_supported();
+  if (ret < 0)
+    {
+      return ret;
+    }
+
   ninfo("connect '%s'\n", g_essid);
   ret = wifi_management_connect(g_essid,
                                 g_passwd[0] ? g_passwd : NULL, 1);

Reply via email to