From 2e53c6ba6fb4e3028de910bc2fe1f22460796647 Mon Sep 17 00:00:00 2001 From: Triveni Danda Date: Thu, 27 Mar 2025 16:37:18 +0530 Subject: [PATCH 01/12] [nrf fromtree] wifi: shell: Add support for EAP-TLS method Add support to read identity and private key password if configured in Enterprise mode. Signed-off-by: Triveni Danda (cherry picked from commit 589333e4d9a5765777229374187f4fb07e8103d6) (cherry picked from commit a90c3f7c3bcb1ad2cd77cbbe32c6ae585d38b874) --- subsys/net/l2/wifi/wifi_mgmt.c | 33 +++++++ .../net/lib/wifi_credentials/CMakeLists.txt | 40 +++++++++ .../lib/wifi_credentials/wifi_credentials.c | 1 + .../wifi_credentials/wifi_credentials_shell.c | 87 +++++++++++++++++++ 4 files changed, 161 insertions(+) diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 0009467abe3..251068d1614 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -1310,6 +1310,9 @@ static int __stored_creds_to_params(struct wifi_credentials_personal *creds, { char *ssid = NULL; char *psk = NULL; +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + char *key_passwd = NULL; +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ int ret; /* SSID */ @@ -1355,6 +1358,29 @@ static int __stored_creds_to_params(struct wifi_credentials_personal *creds, /* Defaults */ params->security = creds->header.type; +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + if (params->security == WIFI_SECURITY_TYPE_EAP_TLS) { + if (creds->header.key_passwd_length > 0) { + key_passwd = (char *)k_malloc(creds->header.key_passwd_length + 1); + if (!key_passwd) { + LOG_ERR("Failed to allocate memory for key_passwd\n"); + ret = -ENOMEM; + goto err_out; + } + memset(key_passwd, 0, creds->header.key_passwd_length + 1); + ret = snprintf(key_passwd, creds->header.key_passwd_length + 1, "%s", + creds->header.key_passwd); + if (ret > creds->header.key_passwd_length) { + LOG_ERR("key_passwd string truncated\n"); + ret = -EINVAL; + goto err_out; + } + params->key_passwd = key_passwd; + params->key_passwd_length = creds->header.key_passwd_length; + } + } +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ + /* If channel is set to 0 we default to ANY. 0 is not a valid Wi-Fi channel. */ params->channel = (creds->header.channel != 0) ? creds->header.channel : WIFI_CHANNEL_ANY; params->timeout = (creds->header.timeout != 0) @@ -1395,6 +1421,13 @@ static int __stored_creds_to_params(struct wifi_credentials_personal *creds, psk = NULL; } +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + if (key_passwd) { + k_free(key_passwd); + key_passwd = NULL; + } +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ + return ret; } diff --git a/subsys/net/lib/wifi_credentials/CMakeLists.txt b/subsys/net/lib/wifi_credentials/CMakeLists.txt index bb8222bd818..532d7a5a628 100644 --- a/subsys/net/lib/wifi_credentials/CMakeLists.txt +++ b/subsys/net/lib/wifi_credentials/CMakeLists.txt @@ -34,3 +34,43 @@ if(WIFI_CREDENTIALS_STATIC_SSID) "Static Wi-Fi configuration is used, please remove before deployment!" ) endif() + +if(DEFINED CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE AND NOT DEFINED CONFIG_NET_L2_WIFI_SHELL) + # Wi-Fi Enterprise test certificates handling + set(gen_inc_dir ${ZEPHYR_BINARY_DIR}/misc/generated) + set(gen_dir ${gen_inc_dir}/wifi_enterprise_test_certs) + if(NOT DEFINED WIFI_TEST_CERTS_DIR) + set(WIFI_TEST_CERTS_DIR ${ZEPHYR_BASE}/samples/net/wifi/test_certs/rsa3k) + endif() + # Create output directory for test certs + file(MAKE_DIRECTORY ${gen_dir}) + + # convert .pem files to array data at build time + zephyr_include_directories(${gen_inc_dir}) + + foreach(cert_file IN ITEMS + ${WIFI_TEST_CERTS_DIR}/client.pem + ${WIFI_TEST_CERTS_DIR}/client-key.pem + ${WIFI_TEST_CERTS_DIR}/ca.pem + ${WIFI_TEST_CERTS_DIR}/client2.pem + ${WIFI_TEST_CERTS_DIR}/client-key2.pem + ${WIFI_TEST_CERTS_DIR}/ca2.pem + ) + + if(EXISTS ${cert_file}) + get_filename_component(cert_name ${cert_file} NAME) + generate_inc_file_for_target( + app + ${cert_file} + ${gen_dir}/${cert_name}.inc + ) + else() + get_filename_component(cert_name ${cert_file} NAME) + file(WRITE ${gen_dir}/${cert_name}.inc "// Empty file generated because ${cert_file} does not exist\n") + endif() + endforeach() + + # Add explicit dependency on app target for ZEPHYR_CURRENT_LIBRARY, so these + # headers are generated at the correct point in the build + add_dependencies(${ZEPHYR_CURRENT_LIBRARY} app) +endif() diff --git a/subsys/net/lib/wifi_credentials/wifi_credentials.c b/subsys/net/lib/wifi_credentials/wifi_credentials.c index a91ea8dd542..6239ebeb3ff 100644 --- a/subsys/net/lib/wifi_credentials/wifi_credentials.c +++ b/subsys/net/lib/wifi_credentials/wifi_credentials.c @@ -136,6 +136,7 @@ int wifi_credentials_get_by_ssid_personal_struct(const char *ssid, size_t ssid_l buf->header.type != WIFI_SECURITY_TYPE_PSK && buf->header.type != WIFI_SECURITY_TYPE_PSK_SHA256 && buf->header.type != WIFI_SECURITY_TYPE_SAE && + buf->header.type != WIFI_SECURITY_TYPE_EAP_TLS && buf->header.type != WIFI_SECURITY_TYPE_WPA_PSK) { LOG_ERR("Requested WiFi credentials entry is corrupted"); ret = -EPROTO; diff --git a/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c b/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c index 23e0373b66e..eba9df4fa9e 100644 --- a/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c +++ b/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c @@ -25,6 +25,63 @@ #define MAX_BANDS_STR_LEN 64 #define MACSTR "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx" +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE +static const char ca_cert_test[] = { + #include + '\0' +}; + +static const char client_cert_test[] = { + #include + '\0' +}; + +static const char client_key_test[] = { + #include + '\0' +}; + +static const char ca_cert2_test[] = { + #include + '\0'}; + +static const char client_cert2_test[] = { + #include + '\0'}; + +static const char client_key2_test[] = { + #include + '\0'}; +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ + +#if defined CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE || \ + defined CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE +static int cmd_wifi_set_enterprise_creds(const struct shell *sh, struct net_if *iface) +{ + struct wifi_enterprise_creds_params params = {0}; + + params.ca_cert = (uint8_t *)ca_cert_test; + params.ca_cert_len = ARRAY_SIZE(ca_cert_test); + params.client_cert = (uint8_t *)client_cert_test; + params.client_cert_len = ARRAY_SIZE(client_cert_test); + params.client_key = (uint8_t *)client_key_test; + params.client_key_len = ARRAY_SIZE(client_key_test); + params.ca_cert2 = (uint8_t *)ca_cert2_test; + params.ca_cert2_len = ARRAY_SIZE(ca_cert2_test); + params.client_cert2 = (uint8_t *)client_cert2_test; + params.client_cert2_len = ARRAY_SIZE(client_cert2_test); + params.client_key2 = (uint8_t *)client_key2_test; + params.client_key2_len = ARRAY_SIZE(client_key2_test); + + if (net_mgmt(NET_REQUEST_WIFI_ENTERPRISE_CREDS, iface, ¶ms, sizeof(params))) { + shell_warn(sh, "Set enterprise credentials failed\n"); + return -1; + } + + return 0; +} +#endif + static void print_network_info(void *cb_arg, const char *ssid, size_t ssid_len) { int ret = 0; @@ -53,6 +110,23 @@ static void print_network_info(void *cb_arg, const char *ssid, size_t ssid_len) creds.password, creds.password_len); } +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + if (creds.header.type == WIFI_SECURITY_TYPE_EAP_TLS) { + if (creds.header.key_passwd_length > 0) { + shell_fprintf(sh, SHELL_VT100_COLOR_DEFAULT, + ", key_passwd: \"%.*s\", key_passwd_len: %d", + creds.header.key_passwd_length, creds.header.key_passwd, + creds.header.key_passwd_length); + } + if (creds.header.aid_length > 0) { + shell_fprintf(sh, SHELL_VT100_COLOR_DEFAULT, + ", anon_id: \"%.*s\", anon_id_len: %d", + creds.header.aid_length, creds.header.anon_id, + creds.header.aid_length); + } + } +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ + if (creds.header.flags & WIFI_CREDENTIALS_FLAG_BSSID) { shell_fprintf(sh, SHELL_VT100_COLOR_DEFAULT, ", bssid: " MACSTR, creds.header.bssid[0], creds.header.bssid[1], creds.header.bssid[2], @@ -266,6 +340,19 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[]) return -EINVAL; } +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + struct net_if *iface = net_if_get_first_by_type(&NET_L2_GET_NAME(ETHERNET)); + + /* Load the enterprise credentials if needed */ + if (creds.header.type == WIFI_SECURITY_TYPE_EAP_TLS || + creds.header.type == WIFI_SECURITY_TYPE_EAP_PEAP_MSCHAPV2 || + creds.header.type == WIFI_SECURITY_TYPE_EAP_PEAP_GTC || + creds.header.type == WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2 || + creds.header.type == WIFI_SECURITY_TYPE_EAP_PEAP_TLS) { + cmd_wifi_set_enterprise_creds(sh, iface); + } +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ + return wifi_credentials_set_personal_struct(&creds); } From 0a6021881f70bbd28b74122dc663eb881445c002 Mon Sep 17 00:00:00 2001 From: Triveni Danda Date: Tue, 1 Apr 2025 14:34:12 +0530 Subject: [PATCH 02/12] [nrf fromtree] net: Fix Kconfig check for enterprise mode Fix the kconfig check for enterprise crypto support in AP mode. Also, remove the unnecessary Hostapd enterprise crypto check in credentials code. Signed-off-by: Triveni Danda (cherry picked from commit b3ea4f8d5c9b39d43b4d074b4e25bbc7a14e6e2d) (cherry picked from commit 75d5c70e7640212b56d41da1e7ca54456b67b4c7) --- subsys/net/l2/wifi/wifi_shell.c | 2 +- subsys/net/lib/wifi_credentials/wifi_credentials_shell.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 5847fe218e9..83f4e2abcde 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -2136,7 +2136,7 @@ static int cmd_wifi_ap_enable(const struct shell *sh, size_t argc, return -ENOEXEC; } -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE +#ifdef CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE /* Load the enterprise credentials if needed */ if (cnx_params.security == WIFI_SECURITY_TYPE_EAP_TLS || cnx_params.security == WIFI_SECURITY_TYPE_EAP_PEAP_MSCHAPV2 || diff --git a/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c b/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c index eba9df4fa9e..4a51de48e12 100644 --- a/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c +++ b/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c @@ -54,8 +54,7 @@ static const char client_key2_test[] = { '\0'}; #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ -#if defined CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE || \ - defined CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE +#if defined CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE static int cmd_wifi_set_enterprise_creds(const struct shell *sh, struct net_if *iface) { struct wifi_enterprise_creds_params params = {0}; @@ -80,7 +79,7 @@ static int cmd_wifi_set_enterprise_creds(const struct shell *sh, struct net_if * return 0; } -#endif +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ static void print_network_info(void *cb_arg, const char *ssid, size_t ssid_len) { From faa3bd25e041f891b23175948b9010b44fcf33fc Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Thu, 30 Jan 2025 01:19:03 +0530 Subject: [PATCH 03/12] [nrf fromtree] modules: hostap: Decrease supplicant thread stack size Based on few tests, it was observed that WPA supplicant's maximum usage for connection and disconnection is 4360. This would save ~4K which is huge as we have a crunch for RAM. This was missed when hostap was upstreamed from NCS. Signed-off-by: Chaitanya Tata (cherry picked from commit 83592e818b76414172458fb872527ebc682491ba) (cherry picked from commit 88c6921665ebe1667eeb49c4254b838855270e52) --- modules/hostap/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index 74c80256b16..89c16a727b6 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -31,7 +31,7 @@ config HEAP_MEM_POOL_ADD_SIZE_HOSTAP config WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE int "Stack size for wpa_supplicant thread" - default 8192 + default 5200 config WIFI_NM_WPA_SUPPLICANT_WQ_STACK_SIZE int "Stack size for wpa_supplicant iface workqueue" From 002a5c2e9e5bbb78bd1a36f9f3d5fbf9c84bc5dc Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 5 Feb 2025 21:03:37 +0530 Subject: [PATCH 04/12] [nrf fromtree] modules: hostap: Fix SoF When connecting to a WPA3 connection, the max stack size observed was 5456, fix the SoF by increasing by 200bytes (cushion added). Signed-off-by: Chaitanya Tata (cherry picked from commit 24cbc8805b4fddc0fd951aa88b73ea57848922f6) (cherry picked from commit 2861e275f068a5e3bf3aaf713c8723938309f426) --- modules/hostap/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index 89c16a727b6..f141cf39597 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -31,7 +31,7 @@ config HEAP_MEM_POOL_ADD_SIZE_HOSTAP config WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE int "Stack size for wpa_supplicant thread" - default 5200 + default 5600 config WIFI_NM_WPA_SUPPLICANT_WQ_STACK_SIZE int "Stack size for wpa_supplicant iface workqueue" From af33ef41aa33e03aeebc4fdfdbd61e2361d2decc Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 5 Feb 2025 21:06:19 +0530 Subject: [PATCH 05/12] [nrf fromtree] modules: hostap: Reduce workqueue stack During experiments it was observed that workqueue uses a maximum of 3872 bytes, so, with cushion added set it to 4096. Signed-off-by: Chaitanya Tata (cherry picked from commit 96dc3d3311dd1978833c149065473403190f848c) (cherry picked from commit ef18ad8f666b4bd5bbd4cf46a968ed41e282996a) --- modules/hostap/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index f141cf39597..11680d77763 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -35,7 +35,7 @@ config WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE config WIFI_NM_WPA_SUPPLICANT_WQ_STACK_SIZE int "Stack size for wpa_supplicant iface workqueue" - default 6144 + default 4096 config WIFI_NM_WPA_SUPPLICANT_WQ_PRIO int "Thread priority of wpa_supplicant iface workqueue" From 82de494604823e5117526a8d3a29b04cd3385ab5 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Mon, 10 Feb 2025 21:08:37 +0530 Subject: [PATCH 06/12] [nrf fromtree] modules: hostap: Fix the SoF in iface_wq In case interface is UP, the interface is added to WPA supplicant in the iface_wq itself and the max stack size is 4264, so, increase the stack size of the iface_wq. If the interface is added via net_mgmt thread then it works fine. Signed-off-by: Chaitanya Tata (cherry picked from commit e2bf746fe273d99b7293f75b4206e5ec2ffe8841) (cherry picked from commit e785deddb071e059329c507a5b9c1505171d0f88) --- modules/hostap/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index 11680d77763..a67569263d1 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -35,7 +35,7 @@ config WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE config WIFI_NM_WPA_SUPPLICANT_WQ_STACK_SIZE int "Stack size for wpa_supplicant iface workqueue" - default 4096 + default 4400 config WIFI_NM_WPA_SUPPLICANT_WQ_PRIO int "Thread priority of wpa_supplicant iface workqueue" From 58429d3e358ef693e7c81ff4a269919afb40d650 Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Wed, 19 Mar 2025 23:47:37 +0530 Subject: [PATCH 07/12] [nrf fromtree] modules: hostap: Fix issue with enterprise mode connection Increase stack size of supplicant thread to fix crash seen during enterprise mode connection. Increase heap requirement of hostap to handle TLS processing failures. Signed-off-by: Ravi Dondaputi (cherry picked from commit d073e622f51589e649434e5c8939743d09e57779) (cherry picked from commit ae37a77639357487a146c59708f75410b9fb0110) --- modules/hostap/Kconfig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index a67569263d1..de5078bcaee 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -25,12 +25,16 @@ if WIFI_NM_WPA_SUPPLICANT config HEAP_MEM_POOL_ADD_SIZE_HOSTAP def_int 66560 if WIFI_NM_HOSTAPD_AP - def_int 41808 if WIFI_NM_WPA_SUPPLICANT_AP || WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + def_int 48000 if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + def_int 41808 if WIFI_NM_WPA_SUPPLICANT_AP # 30K is mandatory, but might need more for long duration use cases def_int 30000 config WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE int "Stack size for wpa_supplicant thread" + # TODO: Providing higher stack size for Enterprise mode to fix stack + # overflow issues. Need to identify the cause for higher stack usage. + default 8192 if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE default 5600 config WIFI_NM_WPA_SUPPLICANT_WQ_STACK_SIZE From c927e2316c4c66e40b4969113cee7a22ffb8c075 Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Tue, 15 Apr 2025 17:32:28 +0530 Subject: [PATCH 08/12] [nrf fromlist] net: lib: wifi_credentials: Add support for Enterprise security Add support for configuring enterprise mode security. Fixes SHEL-3573. Upstream PR #: 88653 Signed-off-by: Ravi Dondaputi (cherry picked from commit 5ebd0330bd274557fc73455f1eac6ce706a2fea8) --- subsys/net/lib/wifi_credentials/Kconfig | 26 ++ .../wifi_credentials/wifi_credentials_shell.c | 224 ++++++++++++++++-- 2 files changed, 234 insertions(+), 16 deletions(-) diff --git a/subsys/net/lib/wifi_credentials/Kconfig b/subsys/net/lib/wifi_credentials/Kconfig index f50e210b080..d0843d689a2 100644 --- a/subsys/net/lib/wifi_credentials/Kconfig +++ b/subsys/net/lib/wifi_credentials/Kconfig @@ -73,6 +73,32 @@ config WIFI_CREDENTIALS_CONNECT_STORED_CONNECTION_TIMEOUT help Wait period before falling back to the next entry in the list of stored SSIDs. + +if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + +config WIFI_CREDENTIALS_RUNTIME_CERTIFICATES + bool "Provide Wi-Fi enterprise security certificates at run-time" + select TLS_CREDENTIALS + select TLS_CREDENTIALS_SHELL + select BASE64 + default y if WIFI_SHELL_RUNTIME_CERTIFICATES + help + This option enables providing Wi-Fi enterprise security certificates at run-time. + Uses the TLS credentials subsystem to store and manage the certificates. + +if WIFI_CREDENTIALS_RUNTIME_CERTIFICATES + +config HEAP_MEM_POOL_ADD_SIZE_WIFI_CERT + int "Wi-Fi enterprise security certificates memory pool size" + # STA - 6 certs and each assume 1500 bytes + default 12000 + help + The size of the memory pool used by the Wi-Fi enterprise security certificates. + +endif # WIFI_CREDENTIALS_RUNTIME_CERTIFICATES + +endif # WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + endif # WIFI_CREDENTIALS_CONNECT_STORED endif # WIFI_CREDENTIALS diff --git a/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c b/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c index 4a51de48e12..c5b8c2a88a3 100644 --- a/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c +++ b/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c @@ -22,10 +22,33 @@ #include +LOG_MODULE_REGISTER(wifi_credentials_shell, CONFIG_WIFI_CREDENTIALS_LOG_LEVEL); + #define MAX_BANDS_STR_LEN 64 #define MACSTR "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx" #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE +#ifdef CONFIG_WIFI_CREDENTIALS_RUNTIME_CERTIFICATES +#include +enum wifi_enterprise_cert_sec_tags { + WIFI_CERT_CA_SEC_TAG = 0x1020001, + WIFI_CERT_CLIENT_KEY_SEC_TAG, + WIFI_CERT_SERVER_KEY_SEC_TAG, + WIFI_CERT_CLIENT_SEC_TAG, + WIFI_CERT_SERVER_SEC_TAG, + /* Phase 2 */ + WIFI_CERT_CA_P2_SEC_TAG, + WIFI_CERT_CLIENT_KEY_P2_SEC_TAG, + WIFI_CERT_CLIENT_P2_SEC_TAG, +}; + +struct wifi_cert_data { + enum tls_credential_type type; + uint32_t sec_tag; + uint8_t **data; + size_t *len; +}; +#else static const char ca_cert_test[] = { #include '\0' @@ -52,25 +75,184 @@ static const char client_cert2_test[] = { static const char client_key2_test[] = { #include '\0'}; +#endif /* CONFIG_WIFI_CREDENTIALS_RUNTIME_CERTIFICATES */ #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ #if defined CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE -static int cmd_wifi_set_enterprise_creds(const struct shell *sh, struct net_if *iface) +#ifdef CONFIG_WIFI_CREDENTIALS_RUNTIME_CERTIFICATES + +struct wifi_enterprise_creds_params enterprise_creds_params; + +static int process_certificates(struct wifi_cert_data *certs, size_t cert_count) +{ + for (size_t i = 0; i < cert_count; i++) { + int err; + size_t len = 0; + uint8_t *cert_tmp; + + err = tls_credential_get(certs[i].sec_tag, certs[i].type, NULL, &len); + if (err != -EFBIG) { + LOG_ERR("Failed to get credential tag: %d length, err: %d", + certs[i].sec_tag, err); + return err; + } + + cert_tmp = k_malloc(len); + if (!cert_tmp) { + LOG_ERR("Failed to allocate memory for credential tag: %d", + certs[i].sec_tag); + return -ENOMEM; + } + + err = tls_credential_get(certs[i].sec_tag, certs[i].type, cert_tmp, &len); + if (err) { + LOG_ERR("Failed to get credential tag: %d", certs[i].sec_tag); + k_free(cert_tmp); + return err; + } + + *certs[i].data = cert_tmp; + *certs[i].len = len; + } + + return 0; +} + +static void set_enterprise_creds_params(struct wifi_enterprise_creds_params *params, + bool is_ap) +{ + struct wifi_cert_data certs_common[] = { + { + .type = TLS_CREDENTIAL_CA_CERTIFICATE, + .sec_tag = WIFI_CERT_CA_SEC_TAG, + .data = ¶ms->ca_cert, + .len = ¶ms->ca_cert_len, + }, + }; + + struct wifi_cert_data certs_sta[] = { + { + .type = TLS_CREDENTIAL_PRIVATE_KEY, + .sec_tag = WIFI_CERT_CLIENT_KEY_SEC_TAG, + .data = ¶ms->client_key, + .len = ¶ms->client_key_len, + }, + { + .type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE, + .sec_tag = WIFI_CERT_CLIENT_SEC_TAG, + .data = ¶ms->client_cert, + .len = ¶ms->client_cert_len, + }, + { + .type = TLS_CREDENTIAL_CA_CERTIFICATE, + .sec_tag = WIFI_CERT_CA_P2_SEC_TAG, + .data = ¶ms->ca_cert2, + .len = ¶ms->ca_cert2_len, + }, + { + .type = TLS_CREDENTIAL_PRIVATE_KEY, + .sec_tag = WIFI_CERT_CLIENT_KEY_P2_SEC_TAG, + .data = ¶ms->client_key2, + .len = ¶ms->client_key2_len, + }, + { + .type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE, + .sec_tag = WIFI_CERT_CLIENT_P2_SEC_TAG, + .data = ¶ms->client_cert2, + .len = ¶ms->client_cert2_len, + }, + }; + + memset(params, 0, sizeof(*params)); + + /* Process common certificates */ + if (process_certificates(certs_common, ARRAY_SIZE(certs_common)) != 0) { + goto cleanup; + } + + /* Process STA-specific certificates */ + if (!is_ap) { + if (process_certificates(certs_sta, ARRAY_SIZE(certs_sta)) != 0) { + goto cleanup; + } + } + + memcpy(&enterprise_creds_params, params, sizeof(*params)); + return; + +cleanup: + for (size_t i = 0; i < ARRAY_SIZE(certs_common); i++) { + if (certs_common[i].data) { + k_free(*certs_common[i].data); + *certs_common[i].data = NULL; + } + } + + if (!is_ap) { + for (size_t i = 0; i < ARRAY_SIZE(certs_sta); i++) { + if (certs_sta[i].data) { + k_free(*certs_sta[i].data); + *certs_sta[i].data = NULL; + } + } + } + +} + +static void clear_enterprise_creds_params(struct wifi_enterprise_creds_params *params) +{ + if (params == NULL) { + return; + } + + const uint8_t *certs[] = { + params->ca_cert, + params->client_cert, + params->client_key, + params->ca_cert2, + params->client_cert2, + params->client_key2, + }; + + for (size_t i = 0; i < ARRAY_SIZE(certs); i++) { + k_free((void *)certs[i]); + } + memset(params, 0, sizeof(*params)); +} +#else +static void set_enterprise_creds_params(struct wifi_enterprise_creds_params *params, + bool is_ap) +{ + params->ca_cert = (uint8_t *)ca_cert_test; + params->ca_cert_len = ARRAY_SIZE(ca_cert_test); + + if (!is_ap) { + params->client_cert = (uint8_t *)client_cert_test; + params->client_cert_len = ARRAY_SIZE(client_cert_test); + params->client_key = (uint8_t *)client_key_test; + params->client_key_len = ARRAY_SIZE(client_key_test); + params->ca_cert2 = (uint8_t *)ca_cert2_test; + params->ca_cert2_len = ARRAY_SIZE(ca_cert2_test); + params->client_cert2 = (uint8_t *)client_cert2_test; + params->client_cert2_len = ARRAY_SIZE(client_cert2_test); + params->client_key2 = (uint8_t *)client_key2_test; + params->client_key2_len = ARRAY_SIZE(client_key2_test); + + return; + } +} +#endif /* CONFIG_WIFI_CREDENTIALS_RUNTIME_CERTIFICATES */ + +static int wifi_set_enterprise_creds(const struct shell *sh, struct net_if *iface, + bool is_ap) { struct wifi_enterprise_creds_params params = {0}; - params.ca_cert = (uint8_t *)ca_cert_test; - params.ca_cert_len = ARRAY_SIZE(ca_cert_test); - params.client_cert = (uint8_t *)client_cert_test; - params.client_cert_len = ARRAY_SIZE(client_cert_test); - params.client_key = (uint8_t *)client_key_test; - params.client_key_len = ARRAY_SIZE(client_key_test); - params.ca_cert2 = (uint8_t *)ca_cert2_test; - params.ca_cert2_len = ARRAY_SIZE(ca_cert2_test); - params.client_cert2 = (uint8_t *)client_cert2_test; - params.client_cert2_len = ARRAY_SIZE(client_cert2_test); - params.client_key2 = (uint8_t *)client_key2_test; - params.client_key2_len = ARRAY_SIZE(client_key2_test); +#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES + clear_enterprise_creds_params(&enterprise_creds_params); +#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ + + set_enterprise_creds_params(¶ms, is_ap); if (net_mgmt(NET_REQUEST_WIFI_ENTERPRISE_CREDS, iface, ¶ms, sizeof(params))) { shell_warn(sh, "Set enterprise credentials failed\n"); @@ -340,7 +522,7 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[]) } #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE - struct net_if *iface = net_if_get_first_by_type(&NET_L2_GET_NAME(ETHERNET)); + struct net_if *iface = net_if_get_wifi_sta(); /* Load the enterprise credentials if needed */ if (creds.header.type == WIFI_SECURITY_TYPE_EAP_TLS || @@ -348,7 +530,7 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[]) creds.header.type == WIFI_SECURITY_TYPE_EAP_PEAP_GTC || creds.header.type == WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2 || creds.header.type == WIFI_SECURITY_TYPE_EAP_PEAP_TLS) { - cmd_wifi_set_enterprise_creds(sh, iface); + wifi_set_enterprise_creds(sh, iface, 0); } #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ @@ -368,6 +550,12 @@ static int cmd_delete_network(const struct shell *sh, size_t argc, char *argv[]) } shell_print(sh, "\tDeleting network ssid: \"%s\", ssid_len: %d", argv[1], strlen(argv[1])); + +#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES + /* Clear the certificates */ + clear_enterprise_creds_params(&enterprise_creds_params); +#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ + return wifi_credentials_delete_by_ssid(argv[1], strlen(argv[1])); } @@ -381,7 +569,11 @@ static int cmd_list_networks(const struct shell *sh, size_t argc, char *argv[]) static int cmd_auto_connect(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_first_by_type(&NET_L2_GET_NAME(ETHERNET)); + struct net_if *iface = net_if_get_wifi_sta(); + +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + wifi_set_enterprise_creds(sh, iface, 0); +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ int rc = net_mgmt(NET_REQUEST_WIFI_CONNECT_STORED, iface, NULL, 0); if (rc) { From 9d11d03c2a4de8238f9bdeb63a05f82be5c20c38 Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Tue, 15 Apr 2025 17:32:48 +0530 Subject: [PATCH 09/12] [nrf fromlist] net: wifi: shell: Enable Wi-Fi credentials support Enable Wi-Fi credentials support. Update the heap sizes as required for enterprise mode. Upstream PR #: 88653 Signed-off-by: Ravi Dondaputi (cherry picked from commit b2c3f2cb7550cd69075c4ea2df79420b8fb3e226) --- modules/hostap/Kconfig | 2 +- snippets/wifi-enterprise/wifi-enterprise.conf | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index de5078bcaee..3dda5ed7931 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -25,7 +25,7 @@ if WIFI_NM_WPA_SUPPLICANT config HEAP_MEM_POOL_ADD_SIZE_HOSTAP def_int 66560 if WIFI_NM_HOSTAPD_AP - def_int 48000 if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + def_int 55000 if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE def_int 41808 if WIFI_NM_WPA_SUPPLICANT_AP # 30K is mandatory, but might need more for long duration use cases def_int 30000 diff --git a/snippets/wifi-enterprise/wifi-enterprise.conf b/snippets/wifi-enterprise/wifi-enterprise.conf index cf7754989ba..1cc7a575507 100644 --- a/snippets/wifi-enterprise/wifi-enterprise.conf +++ b/snippets/wifi-enterprise/wifi-enterprise.conf @@ -7,6 +7,15 @@ CONFIG_NET_BUF_VARIABLE_DATA_SIZE=y CONFIG_MBEDTLS_ENABLE_HEAP=y CONFIG_MBEDTLS_HEAP_SIZE=70000 +#For use with Wi-Fi Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_FLASH=y +CONFIG_FLASH_PAGE_LAYOUT=y +CONFIG_FLASH_MAP=y +CONFIG_NVS=y +CONFIG_SETTINGS=y +CONFIG_SETTINGS_NVS=y + # For use with TLS credentials CONFIG_TLS_CREDENTIALS_SHELL=y CONFIG_BASE64=y From 5a660c1bd25b4e80d41fd88d95e4274b6f0d896c Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Mon, 21 Apr 2025 18:42:27 +0530 Subject: [PATCH 10/12] [nrf fromlist] snippets: wifi-enterprise: Resize data heap to fix RAM overflow Inclusion of CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES causes build time RAM overflow issues. Decrease NRF_WIFI_DATA_HEAP_SIZE to accommodate the RUNTIME_CERTIFICATES feature. Upstream PR #:88861 Signed-off-by: Ravi Dondaputi (cherry picked from commit a4b75c00cbaad636d9ada55551104a5b88bacc47) --- snippets/wifi-enterprise/wifi-enterprise.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/snippets/wifi-enterprise/wifi-enterprise.conf b/snippets/wifi-enterprise/wifi-enterprise.conf index 1cc7a575507..4de1130cf69 100644 --- a/snippets/wifi-enterprise/wifi-enterprise.conf +++ b/snippets/wifi-enterprise/wifi-enterprise.conf @@ -23,3 +23,4 @@ CONFIG_TLS_CREDENTIALS=y CONFIG_TLS_CREDENTIALS_SHELL_CRED_BUF_SIZE=8192 CONFIG_TLS_MAX_CREDENTIALS_NUMBER=6 CONFIG_HEAP_MEM_POOL_ADD_SIZE_TLS_CRED_SHELL=9000 +CONFIG_NRF_WIFI_DATA_HEAP_SIZE=100000 From 4392c2fab71e9540579b31ab5de96f2c4ed2e755 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 18 Apr 2025 00:10:21 +0530 Subject: [PATCH 11/12] [nrf fromlist] nrf_wifi: Move QSPI defines to buslib These are QSPI related which is part of buslib. Upstream PR #: 88897 Signed-off-by: Chaitanya Tata (cherry picked from commit ad17ea8dad2695860485f75130ec94a1ed3c636f) --- drivers/wifi/nrf_wifi/CMakeLists.txt | 11 ----------- modules/nrf_wifi/bus/CMakeLists.txt | 12 ++++++++++++ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/wifi/nrf_wifi/CMakeLists.txt b/drivers/wifi/nrf_wifi/CMakeLists.txt index d44aa7b98c8..d59a6ef6e9f 100644 --- a/drivers/wifi/nrf_wifi/CMakeLists.txt +++ b/drivers/wifi/nrf_wifi/CMakeLists.txt @@ -70,17 +70,6 @@ zephyr_library_sources_ifdef(CONFIG_NRF70_DEBUG_SHELL src/debug_shell.c ) -zephyr_compile_definitions_ifdef(CONFIG_NRF70_ON_QSPI -# These are XIP related anomalies and aren't applicable for nRF7002 and cause -# throughput issues. - -DNRF53_ERRATA_43_ENABLE_WORKAROUND=0 - -DNRF52_ERRATA_215_ENABLE_WORKAROUND=0 -# nRF70 QSPI doesn't use 192MHz clock and most samples use 128MHz, this can cause anomaly 159 -# but as its rare and not seen in most cases, we can disable it. -# Alternative is 128MHz CPU should be disabled that impacts Wi-Fi performance. - -DNRF53_ERRATA_159_ENABLE_WORKAROUND=0 -) - zephyr_library_link_libraries(nrf70-buslib nrf-wifi-shim) if (CONFIG_NRF_WIFI_PATCHES_BUILTIN) diff --git a/modules/nrf_wifi/bus/CMakeLists.txt b/modules/nrf_wifi/bus/CMakeLists.txt index ac9a2f0fd84..0fc5651a13e 100644 --- a/modules/nrf_wifi/bus/CMakeLists.txt +++ b/modules/nrf_wifi/bus/CMakeLists.txt @@ -12,6 +12,18 @@ endif() set(NRF_WIFI_DIR ${ZEPHYR_CURRENT_MODULE_DIR}) if (CONFIG_NRF70_BUSLIB) + + zephyr_compile_definitions_ifdef(CONFIG_NRF70_ON_QSPI + # These are XIP related anomalies and aren't applicable for nRF7002 and cause + # throughput issues. + -DNRF53_ERRATA_43_ENABLE_WORKAROUND=0 + -DNRF52_ERRATA_215_ENABLE_WORKAROUND=0 + # nRF70 QSPI doesn't use 192MHz clock and most samples use 128MHz, this can cause anomaly 159 + # but as its rare and not seen in most cases, we can disable it. + # Alternative is 128MHz CPU should be disabled that impacts Wi-Fi performance. + -DNRF53_ERRATA_159_ENABLE_WORKAROUND=0 + ) + zephyr_library_named(nrf70-buslib) zephyr_library_include_directories( inc From 1db01927ba8158c388321cd1d3df50256ddf4b9a Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 18 Apr 2025 14:47:22 +0530 Subject: [PATCH 12/12] [nrf fromlist] modules: nrf_wifi: Disable anomalies for both QSPIs These are applicable for Wi-Fi over QSPI (nRF7002DK) or Flash over QSPI (nRF52/53 + nRF7002EK) and as most Wi-Fi samples run on 128MHz (for performance), disable the anomalies for both. Upstream PR #: 88897 Signed-off-by: Chaitanya Tata (cherry picked from commit 63c239c946d1686c51ee0f0d2c2f05badcdc67fb) --- modules/nrf_wifi/bus/CMakeLists.txt | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/modules/nrf_wifi/bus/CMakeLists.txt b/modules/nrf_wifi/bus/CMakeLists.txt index 0fc5651a13e..9eb3b577ffb 100644 --- a/modules/nrf_wifi/bus/CMakeLists.txt +++ b/modules/nrf_wifi/bus/CMakeLists.txt @@ -13,16 +13,18 @@ set(NRF_WIFI_DIR ${ZEPHYR_CURRENT_MODULE_DIR}) if (CONFIG_NRF70_BUSLIB) - zephyr_compile_definitions_ifdef(CONFIG_NRF70_ON_QSPI - # These are XIP related anomalies and aren't applicable for nRF7002 and cause - # throughput issues. - -DNRF53_ERRATA_43_ENABLE_WORKAROUND=0 - -DNRF52_ERRATA_215_ENABLE_WORKAROUND=0 - # nRF70 QSPI doesn't use 192MHz clock and most samples use 128MHz, this can cause anomaly 159 - # but as its rare and not seen in most cases, we can disable it. - # Alternative is 128MHz CPU should be disabled that impacts Wi-Fi performance. - -DNRF53_ERRATA_159_ENABLE_WORKAROUND=0 - ) + if(CONFIG_NRF70_ON_QSPI OR CONFIG_NORDIC_QSPI_NOR) + zephyr_compile_definitions( + # These are XIP related anomalies and aren't applicable for nRF7002 and cause + # throughput issues. + -DNRF53_ERRATA_43_ENABLE_WORKAROUND=0 + -DNRF52_ERRATA_215_ENABLE_WORKAROUND=0 + # nRF70 QSPI doesn't use 192MHz clock and most samples use 128MHz, this can cause anomaly 159 + # but as its rare and not seen in most cases, we can disable it. + # Alternative is 128MHz CPU should be disabled that impacts Wi-Fi performance. + -DNRF53_ERRATA_159_ENABLE_WORKAROUND=0 + ) + endif() zephyr_library_named(nrf70-buslib) zephyr_library_include_directories(