diff --git a/drivers/wifi/nrf_wifi/inc/fmac_main.h b/drivers/wifi/nrf_wifi/inc/fmac_main.h index c193515ae2d..7a863d8b614 100644 --- a/drivers/wifi/nrf_wifi/inc/fmac_main.h +++ b/drivers/wifi/nrf_wifi/inc/fmac_main.h @@ -91,6 +91,7 @@ struct nrf_wifi_vif_ctx_zep { struct k_work_delayable nrf_wifi_rpu_recovery_bringup_work; #endif /* CONFIG_NRF_WIFI_RPU_RECOVERY */ int rts_threshold_value; + unsigned short bss_max_idle_period; }; struct nrf_wifi_vif_ctx_map { diff --git a/drivers/wifi/nrf_wifi/inc/wifi_mgmt.h b/drivers/wifi/nrf_wifi/inc/wifi_mgmt.h index a4ae2030210..9b84427cdca 100644 --- a/drivers/wifi/nrf_wifi/inc/wifi_mgmt.h +++ b/drivers/wifi/nrf_wifi/inc/wifi_mgmt.h @@ -77,4 +77,7 @@ int nrf_wifi_set_rts_threshold(const struct device *dev, int nrf_wifi_get_rts_threshold(const struct device *dev, unsigned int *rts_threshold); + +int nrf_wifi_set_bss_max_idle_period(const struct device *dev, + unsigned short bss_max_idle_period); #endif /* __ZEPHYR_WIFI_MGMT_H__ */ diff --git a/drivers/wifi/nrf_wifi/src/fmac_main.c b/drivers/wifi/nrf_wifi/src/fmac_main.c index 379c3242b18..f2d9aa55af9 100644 --- a/drivers/wifi/nrf_wifi/src/fmac_main.c +++ b/drivers/wifi/nrf_wifi/src/fmac_main.c @@ -858,6 +858,9 @@ static int nrf_wifi_drv_main_zep(const struct device *dev) #endif /* CONFIG_NRF70_RADIO_TEST */ k_mutex_init(&rpu_drv_priv_zep.rpu_ctx_zep.rpu_lock); +#ifndef CONFIG_NRF70_RADIO_TEST + vif_ctx_zep->bss_max_idle_period = USHRT_MAX; +#endif /* !CONFIG_NRF70_RADIO_TEST */ return 0; #ifdef CONFIG_NRF70_RADIO_TEST fmac_deinit: @@ -885,6 +888,7 @@ static const struct wifi_mgmt_ops nrf_wifi_mgmt_ops = { .get_power_save_config = nrf_wifi_get_power_save_config, .set_rts_threshold = nrf_wifi_set_rts_threshold, .get_rts_threshold = nrf_wifi_get_rts_threshold, + .set_bss_max_idle_period = nrf_wifi_set_bss_max_idle_period, #endif #ifdef CONFIG_NRF70_SYSTEM_WITH_RAW_MODES .mode = nrf_wifi_mode, diff --git a/drivers/wifi/nrf_wifi/src/wifi_mgmt.c b/drivers/wifi/nrf_wifi/src/wifi_mgmt.c index a323faf21dd..e9755e80013 100644 --- a/drivers/wifi/nrf_wifi/src/wifi_mgmt.c +++ b/drivers/wifi/nrf_wifi/src/wifi_mgmt.c @@ -1077,3 +1077,56 @@ int nrf_wifi_get_rts_threshold(const struct device *dev, return ret; } + +int nrf_wifi_set_bss_max_idle_period(const struct device *dev, + unsigned short bss_max_idle_period) +{ + struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; + struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; + int ret = -1; + + if (!dev) { + LOG_ERR("%s: dev is NULL", __func__); + return ret; + } + + vif_ctx_zep = dev->data; + + if (!vif_ctx_zep) { + LOG_ERR("%s: vif_ctx_zep is NULL", __func__); + return ret; + } + + rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep; + + if (!rpu_ctx_zep) { + LOG_ERR("%s: rpu_ctx_zep is NULL", __func__); + return ret; + } + + + if (!rpu_ctx_zep->rpu_ctx) { + LOG_ERR("%s: RPU context not initialized", __func__); + return ret; + } + + if (((int)bss_max_idle_period < 0) || + (bss_max_idle_period > 64000)) { + /* 0 or value less than 64000 is passed to f/w. + * All other values considered as invalid. + */ + LOG_ERR("%s: Invalid max_idle_period value : %d", + __func__, (int)bss_max_idle_period); + return ret; + } + + k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER); + + vif_ctx_zep->bss_max_idle_period = bss_max_idle_period; + + ret = 0; + + k_mutex_unlock(&vif_ctx_zep->vif_lock); + + return ret; +} diff --git a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c index d06f0792fa2..1ef412df7f7 100644 --- a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c +++ b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c @@ -931,8 +931,15 @@ int nrf_wifi_wpa_supp_associate(void *if_priv, struct wpa_driver_associate_param assoc_info.use_mfp = NRF_WIFI_MFP_REQUIRED; } - if (params->bss_max_idle_period) { - assoc_info.bss_max_idle_time = params->bss_max_idle_period; + if (vif_ctx_zep->bss_max_idle_period == USHRT_MAX) { + assoc_info.bss_max_idle_time = CONFIG_WIFI_MGMT_BSS_MAX_IDLE_TIME; + } else { + assoc_info.bss_max_idle_time = vif_ctx_zep->bss_max_idle_period; + } + + assoc_info.conn_type = NRF_WIFI_CONN_TYPE_OPEN; + if (!(params->key_mgmt_suite & WPA_KEY_MGMT_NONE)) { + assoc_info.conn_type = NRF_WIFI_CONN_TYPE_SECURE; } status = nrf_wifi_sys_fmac_assoc(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &assoc_info); diff --git a/include/zephyr/net/wifi_certs.h b/include/zephyr/net/wifi_certs.h new file mode 100644 index 00000000000..ea9e02cf104 --- /dev/null +++ b/include/zephyr/net/wifi_certs.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef WIFI_CERTS_H__ +#define WIFI_CERTS_H__ + +#include +#include +#include + +/** + * Set Wi-Fi Enterprise credentials. + * + * Sets up the required credentials for Enterprise mode in both + * Access Point and Station modes. + * + * Certificates typically used: + * - CA certificate + * - Client certificate + * - Client private key + * - Server certificate and server key (for AP mode) + * + * @param iface Network interface + * @param is_ap AP or Station mode + * + * @return 0 if ok, < 0 if error + */ +int wifi_set_enterprise_credentials(struct net_if *iface, bool is_ap); + +/** + * Clear Wi-Fi enterprise credentials + */ +void wifi_clear_enterprise_credentials(void); + +#endif /* WIFI_CERTS_H__ */ diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 8c6654f3ef5..00c83a986ea 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -133,6 +133,8 @@ enum net_request_wifi_cmd { NET_REQUEST_WIFI_CMD_CANDIDATE_SCAN, /** AP WPS config */ NET_REQUEST_WIFI_CMD_AP_WPS_CONFIG, + /** Configure BSS maximum idle period */ + NET_REQUEST_WIFI_CMD_BSS_MAX_IDLE_PERIOD, /** @cond INTERNAL_HIDDEN */ NET_REQUEST_WIFI_CMD_MAX /** @endcond */ @@ -317,6 +319,11 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_START_ROAMING); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_NEIGHBOR_REP_COMPLETE); +#define NET_REQUEST_WIFI_BSS_MAX_IDLE_PERIOD \ + (NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_BSS_MAX_IDLE_PERIOD) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_BSS_MAX_IDLE_PERIOD); + /** @brief Wi-Fi management events */ enum net_event_wifi_cmd { /** Scan results available */ @@ -672,7 +679,7 @@ struct wifi_iface_status { /** is TWT capable? */ bool twt_capable; /** The current 802.11 PHY TX data rate (in Mbps) */ - int current_phy_tx_rate; + float current_phy_tx_rate; }; /** @brief Wi-Fi power save parameters */ @@ -1559,6 +1566,15 @@ struct wifi_mgmt_ops { * @return 0 if ok, < 0 if error */ int (*start_11r_roaming)(const struct device *dev); + /** Set BSS max idle period + * + * @param dev Pointer to the device structure for the driver instance. + * @param BSS max idle period value + * + * @return 0 if ok, < 0 if error + */ + int (*set_bss_max_idle_period)(const struct device *dev, + unsigned short bss_max_idle_period); }; /** Wi-Fi management offload API */ diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index 2056a43e872..8e5f7d348a8 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -24,6 +24,24 @@ config WIFI_NM_WPA_SUPPLICANT if WIFI_NM_WPA_SUPPLICANT +config WIFI_NM_WPA_SUPPLICANT_GLOBAL_HEAP + bool "Use Zephyr kernel heap for Wi-Fi driver" + default y + help + Enable this option to use K_HEAP for memory allocations in supplicant. + +if !WIFI_NM_WPA_SUPPLICANT_GLOBAL_HEAP +config WIFI_NM_WPA_SUPPLICANT_HEAP + int "Dedicated memory pool for wpa_supplicant" + def_int 66560 if WIFI_NM_HOSTAPD_AP + def_int 55000 if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE && WIFI_CREDENTIALS + 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 +endif # !WIFI_NM_WPA_SUPPLICANT_GLOBAL_HEAP + +if WIFI_NM_WPA_SUPPLICANT_GLOBAL_HEAP config HEAP_MEM_POOL_ADD_SIZE_HOSTAP def_int 66560 if WIFI_NM_HOSTAPD_AP def_int 55000 if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE && WIFI_CREDENTIALS @@ -31,6 +49,8 @@ config HEAP_MEM_POOL_ADD_SIZE_HOSTAP def_int 41808 if WIFI_NM_WPA_SUPPLICANT_AP # 30K is mandatory, but might need more for long duration use cases def_int 30000 +endif # WIFI_NM_WPA_SUPPLICANT_GLOBAL_HEAP + config WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE int "Stack size for wpa_supplicant thread" @@ -201,6 +221,7 @@ config WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE select MBEDTLS_X509_CRL_PARSE_C select MBEDTLS_TLS_VERSION_1_2 select NOT_SECURE + select WIFI_CERTIFICATE_LIB depends on !WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE help Enable Enterprise Crypto support for WiFi. This feature @@ -309,6 +330,7 @@ config WIFI_NM_HOSTAPD_AP config WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE bool "Hostapd crypto enterprise support" + select WIFI_CERTIFICATE_LIB depends on WIFI_NM_HOSTAPD_AP if WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE @@ -564,6 +586,9 @@ config ACS config IEEE80211AC bool +config HS20 + bool + config IEEE80211R bool depends on !WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE diff --git a/modules/hostap/src/supp_api.c b/modules/hostap/src/supp_api.c index cde1ef95f47..3679808b3d4 100644 --- a/modules/hostap/src/supp_api.c +++ b/modules/hostap/src/supp_api.c @@ -1811,6 +1811,19 @@ int supplicant_legacy_roam(const struct device *dev) return ret; } +int supplicant_set_bss_max_idle_period(const struct device *dev, + unsigned short bss_max_idle_period) +{ + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_mgmt_api(dev); + + if (!wifi_mgmt_api || !wifi_mgmt_api->set_bss_max_idle_period) { + wpa_printf(MSG_ERROR, "set_bss_max_idle_period is not supported"); + return -ENOTSUP; + } + + return wifi_mgmt_api->set_bss_max_idle_period(dev, bss_max_idle_period); +} + #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM int supplicant_btm_query(const struct device *dev, uint8_t reason) { diff --git a/modules/hostap/src/supp_api.h b/modules/hostap/src/supp_api.h index ddd3c3d6698..bae1c3ab4df 100644 --- a/modules/hostap/src/supp_api.h +++ b/modules/hostap/src/supp_api.h @@ -305,6 +305,15 @@ int supplicant_get_wifi_conn_params(const struct device *dev, */ int supplicant_wps_config(const struct device *dev, struct wifi_wps_config_params *params); +/** @ Set Wi-Fi max idle period + * + * @param dev Wi-Fi interface handle to use + * @param bss_max_idle_period Maximum idle period to set + * @return 0 for OK; -1 for ERROR + */ +int supplicant_set_bss_max_idle_period(const struct device *dev, + unsigned short bss_max_idle_period); + #ifdef CONFIG_AP int set_ap_bandwidth(const struct device *dev, enum wifi_frequency_bandwidths bandwidth); diff --git a/modules/hostap/src/supp_main.c b/modules/hostap/src/supp_main.c index c2a4866b921..849ba834ec1 100644 --- a/modules/hostap/src/supp_main.c +++ b/modules/hostap/src/supp_main.c @@ -83,6 +83,7 @@ static const struct wifi_mgmt_ops mgmt_ops = { #endif .get_conn_params = supplicant_get_wifi_conn_params, .wps_config = supplicant_wps_config, + .set_bss_max_idle_period = supplicant_set_bss_max_idle_period, #ifdef CONFIG_AP .ap_enable = supplicant_ap_enable, .ap_disable = supplicant_ap_disable, diff --git a/subsys/net/l2/wifi/CMakeLists.txt b/subsys/net/l2/wifi/CMakeLists.txt index e1e9606bfd2..63fb98fa6cf 100644 --- a/subsys/net/l2/wifi/CMakeLists.txt +++ b/subsys/net/l2/wifi/CMakeLists.txt @@ -13,6 +13,7 @@ zephyr_library_include_directories_ifdef( ) zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_MGMT wifi_mgmt.c) +zephyr_library_sources_ifdef(CONFIG_WIFI_CERTIFICATE_LIB wifi_certs.c) zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_SHELL wifi_shell.c) zephyr_library_sources_ifdef(CONFIG_WIFI_NM wifi_nm.c) zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_UTILS wifi_utils.c) diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index a2e029a592b..f129c3bf72d 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -126,6 +126,11 @@ config WIFI_ENT_IDENTITY_MAX_USERS help This option defines the maximum number of identity users allowed connection. +config WIFI_CERTIFICATE_LIB + bool + help + Enable this option to process certificates in enterprise mode. + if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE config WIFI_SHELL_RUNTIME_CERTIFICATES @@ -149,3 +154,20 @@ config HEAP_MEM_POOL_ADD_SIZE_WIFI_CERT endif # WIFI_SHELL_RUNTIME_CERTIFICATES endif # WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + + +config WIFI_MGMT_BSS_MAX_IDLE_TIME + int "BSS max idle timeout in seconds" + range 0 64000 + default 300 + help + As per 802.11-2020: 11.21.13 BSS max idle period management + If dot11WirelessManagementImplemented is true, dot11BSSMaxIdlePeriod is + nonzero and dot11BSSMaxIdlePeriodIndicationByNonAPSTA is true, then a + non-S1G non-AP STA shall include a BSS Max Idle Period element + in the (Re)Association Request frame. If the BSS Max Idle Period + element is present in the (Re)Association Request frame received + by a non-S1G AP that has dot11BSSMaxIdlePeriodIndicationByNonAPSTA + equal to true, then the non-S1G AP may choose the non-AP STA’s + preferred maximum idle period. The non-S1G AP indicates its chosen + value to the non-S1G STA in the (Re)Association Response frame. diff --git a/subsys/net/l2/wifi/wifi_certs.c b/subsys/net/l2/wifi/wifi_certs.c new file mode 100644 index 00000000000..545010cbf77 --- /dev/null +++ b/subsys/net/l2/wifi/wifi_certs.c @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(net_wifi_certs, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include + +static struct wifi_enterprise_creds_params enterprise_creds_params = { 0 }; + +#ifdef CONFIG_WIFI_SHELL_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' +}; + +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'}; + +static const char server_cert_test[] = { + #include + '\0' +}; + +static const char server_key_test[] = { + #include + '\0' +}; +#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ + +#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES +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(bool is_ap) +{ + struct wifi_cert_data certs_common[] = { + { + .type = TLS_CREDENTIAL_CA_CERTIFICATE, + .sec_tag = WIFI_CERT_CA_SEC_TAG, + .data = &enterprise_creds_params.ca_cert, + .len = &enterprise_creds_params.ca_cert_len, + }, + }; + struct wifi_cert_data certs_sta[] = { + { + .type = TLS_CREDENTIAL_PRIVATE_KEY, + .sec_tag = WIFI_CERT_CLIENT_KEY_SEC_TAG, + .data = &enterprise_creds_params.client_key, + .len = &enterprise_creds_params.client_key_len, + }, + { + .type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE, + .sec_tag = WIFI_CERT_CLIENT_SEC_TAG, + .data = &enterprise_creds_params.client_cert, + .len = &enterprise_creds_params.client_cert_len, + }, + { + .type = TLS_CREDENTIAL_CA_CERTIFICATE, + .sec_tag = WIFI_CERT_CA_P2_SEC_TAG, + .data = &enterprise_creds_params.ca_cert2, + .len = &enterprise_creds_params.ca_cert2_len, + }, + { + .type = TLS_CREDENTIAL_PRIVATE_KEY, + .sec_tag = WIFI_CERT_CLIENT_KEY_P2_SEC_TAG, + .data = &enterprise_creds_params.client_key2, + .len = &enterprise_creds_params.client_key2_len, + }, + { + .type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE, + .sec_tag = WIFI_CERT_CLIENT_P2_SEC_TAG, + .data = &enterprise_creds_params.client_cert2, + .len = &enterprise_creds_params.client_cert2_len, + }, + }; + + struct wifi_cert_data certs_ap[] = { + { + .type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE, + .sec_tag = WIFI_CERT_SERVER_SEC_TAG, + .data = &enterprise_creds_params.server_cert, + .len = &enterprise_creds_params.server_cert_len, + }, + { + .type = TLS_CREDENTIAL_PRIVATE_KEY, + .sec_tag = WIFI_CERT_SERVER_KEY_SEC_TAG, + .data = &enterprise_creds_params.server_key, + .len = &enterprise_creds_params.server_key_len, + }, + }; + + memset(&enterprise_creds_params, 0, sizeof(struct wifi_enterprise_creds_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; + } + } + + /* Process AP-specific certificates if is_ap is true */ + if (is_ap) { + if (process_certificates(certs_ap, ARRAY_SIZE(certs_ap)) != 0) { + goto cleanup; + } + } + + return; + +cleanup: + for (size_t i = 0; i < ARRAY_SIZE(certs_common); i++) { + if (certs_common[i].data) { + k_free(*certs_common[i].data); + } + } + + 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); + } + } + } + + if (is_ap) { + for (size_t i = 0; i < ARRAY_SIZE(certs_ap); i++) { + if (certs_ap[i].data) { + k_free(*certs_ap[i].data); + } + } + } +} + +void wifi_clear_enterprise_credentials(void) +{ + size_t i; + + const uint8_t *certs[] = { + enterprise_creds_params.ca_cert, + enterprise_creds_params.client_cert, + enterprise_creds_params.client_key, + enterprise_creds_params.server_cert, + enterprise_creds_params.server_key, + enterprise_creds_params.ca_cert2, + enterprise_creds_params.client_cert2, + enterprise_creds_params.client_key2, + }; + + for (i = 0; i < ARRAY_SIZE(certs); i++) { + k_free((void *)certs[i]); + } + memset(&enterprise_creds_params, 0, sizeof(struct wifi_enterprise_creds_params)); +} +#else +int config_process_blob(struct wpa_config *config, char *name, uint8_t *data, + uint32_t data_len) +{ + struct wpa_config_blob *blob; + + if (!data || !data_len) { + return -1; + } + + blob = os_zalloc(sizeof(*blob)); + if (blob == NULL) { + return -1; + } + + blob->data = os_zalloc(data_len); + if (blob->data == NULL) { + os_free(blob); + return -1; + } + + blob->name = os_strdup(name); + + if (blob->name == NULL) { + wpa_config_free_blob(blob); + return -1; + } + + os_memcpy(blob->data, data, data_len); + blob->len = data_len; + + wpa_config_set_blob(config, blob); + + return 0; +} + +int process_certificates(void) +{ + struct wpa_supplicant *wpa_s; + int ret; + char if_name[CONFIG_NET_INTERFACE_NAME_LEN + 1]; + struct net_if *iface = net_if_get_wifi_sta(); + + ret = net_if_get_name(iface, if_name, sizeof(if_name)); + if (!ret) { + LOG_ERR("Cannot get interface name (%d)", ret); + return -1; + } + + wpa_s = zephyr_get_handle_by_ifname(if_name); + if (!wpa_s) { + LOG_ERR("Unable to find the interface: %s, quitting", if_name); + return -1; + } + + wifi_set_enterprise_credentials(iface, 0); + + if (config_process_blob(wpa_s->conf, "ca_cert", + enterprise_creds_params.ca_cert, + enterprise_creds_params.ca_cert_len)) { + return -1; + } + + if (config_process_blob(wpa_s->conf, "client_cert", + enterprise_creds_params.client_cert, + enterprise_creds_params.client_cert_len)) { + return -1; + } + + if (config_process_blob(wpa_s->conf, "private_key", + enterprise_creds_params.client_key, + enterprise_creds_params.client_key_len)) { + return -1; + } + + return 0; +} + +static void set_enterprise_creds_params(bool is_ap) +{ + enterprise_creds_params.ca_cert = (uint8_t *)ca_cert_test; + enterprise_creds_params.ca_cert_len = ARRAY_SIZE(ca_cert_test); + + if (!is_ap) { + enterprise_creds_params.client_cert = (uint8_t *)client_cert_test; + enterprise_creds_params.client_cert_len = ARRAY_SIZE(client_cert_test); + enterprise_creds_params.client_key = (uint8_t *)client_key_test; + enterprise_creds_params.client_key_len = ARRAY_SIZE(client_key_test); + enterprise_creds_params.ca_cert2 = (uint8_t *)ca_cert2_test; + enterprise_creds_params.ca_cert2_len = ARRAY_SIZE(ca_cert2_test); + enterprise_creds_params.client_cert2 = (uint8_t *)client_cert2_test; + enterprise_creds_params.client_cert2_len = ARRAY_SIZE(client_cert2_test); + enterprise_creds_params.client_key2 = (uint8_t *)client_key2_test; + enterprise_creds_params.client_key2_len = ARRAY_SIZE(client_key2_test); + + return; + } + + enterprise_creds_params.server_cert = (uint8_t *)server_cert_test; + enterprise_creds_params.server_cert_len = ARRAY_SIZE(server_cert_test); + enterprise_creds_params.server_key = (uint8_t *)server_key_test; + enterprise_creds_params.server_key_len = ARRAY_SIZE(server_key_test); +} + +void wifi_clear_enterprise_credentials(void) +{ + /** + * No operation needed because Wi-Fi credentials + * are statically configured at build time and + * no dynamic memory needs to be freed. + */ +} +#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ + +int wifi_set_enterprise_credentials(struct net_if *iface, bool is_ap) +{ +#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES + wifi_clear_enterprise_credentials(); +#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ + set_enterprise_creds_params(is_ap); + if (net_mgmt(NET_REQUEST_WIFI_ENTERPRISE_CREDS, iface, + &enterprise_creds_params, sizeof(enterprise_creds_params))) { + LOG_WRN("Set enterprise credentials failed\n"); + return -1; + } + + return 0; +} diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index dc52c42a5c2..67f1f68e5a5 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -1403,6 +1403,31 @@ static int wifi_set_enterprise_creds(uint32_t mgmt_request, struct net_if *iface NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_ENTERPRISE_CREDS, wifi_set_enterprise_creds); #endif +static int wifi_set_bss_max_idle_period(uint32_t mgmt_request, struct net_if *iface, + void *data, size_t len) +{ + const struct device *dev = net_if_get_device(iface); + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); + unsigned short *bss_max_idle_period = data; + + if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_bss_max_idle_period == NULL) { + return -ENOTSUP; + } + + if (!net_if_is_admin_up(iface)) { + return -ENETDOWN; + } + + if (!data || len != sizeof(*bss_max_idle_period)) { + return -EINVAL; + } + + return wifi_mgmt_api->set_bss_max_idle_period(dev, *bss_max_idle_period); +} + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_BSS_MAX_IDLE_PERIOD, + wifi_set_bss_max_idle_period); + #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, struct wifi_raw_scan_result *raw_scan_result) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index af0db05855f..6ef17817aa4 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -30,67 +30,10 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); #include "net_shell_private.h" #include -#if defined CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE || \ - defined CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE -#ifdef CONFIG_WIFI_SHELL_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' -}; - -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'}; - -static const char server_cert_test[] = { - #include - '\0' -}; -static const char server_key_test[] = { - #include - '\0' -}; -#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ -#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ +#ifdef CONFIG_WIFI_CERTIFICATE_LIB +#include +#endif #define WIFI_SHELL_MODULE "wifi" @@ -128,12 +71,6 @@ static struct { }; uint8_t all; }; -#if defined CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE || \ - defined CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE -#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES - struct wifi_enterprise_creds_params enterprise_creds_params; -#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ -#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ } context; static struct net_mgmt_event_callback wifi_shell_mgmt_cb; @@ -201,223 +138,6 @@ static struct net_if *get_iface(enum iface_type type, int argc, char *argv[]) return iface; } -#if defined CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE || \ - defined CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE -#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES -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, - }, - }; - - struct wifi_cert_data certs_ap[] = { - { - .type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE, - .sec_tag = WIFI_CERT_SERVER_SEC_TAG, - .data = ¶ms->server_cert, - .len = ¶ms->server_cert_len, - }, - { - .type = TLS_CREDENTIAL_PRIVATE_KEY, - .sec_tag = WIFI_CERT_SERVER_KEY_SEC_TAG, - .data = ¶ms->server_key, - .len = ¶ms->server_key_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; - } - } - - /* Process AP-specific certificates if is_ap is true */ - if (is_ap) { - if (process_certificates(certs_ap, ARRAY_SIZE(certs_ap)) != 0) { - goto cleanup; - } - } - - memcpy(&context.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); - } - } - - 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); - } - } - } - - if (is_ap) { - for (size_t i = 0; i < ARRAY_SIZE(certs_ap); i++) { - if (certs_ap[i].data) { - k_free(*certs_ap[i].data); - } - } - } -} - -static void clear_enterprise_creds_params(struct wifi_enterprise_creds_params *params) -{ - size_t i; - - if (!params) { - return; - } - - const uint8_t *certs[] = { - params->ca_cert, - params->client_cert, - params->client_key, - params->server_cert, - params->server_key, - params->ca_cert2, - params->client_cert2, - params->client_key2, - }; - - for (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; - } - - params->server_cert = (uint8_t *)server_cert_test; - params->server_cert_len = ARRAY_SIZE(server_cert_test); - params->server_key = (uint8_t *)server_key_test; - params->server_key_len = ARRAY_SIZE(server_key_test); -} -#endif /* CONFIG_WIFI_SHELL_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}; - -#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES - clear_enterprise_creds_params(&context.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))) { - PR_WARNING("Set enterprise credentials failed\n"); - return -1; - } - - return 0; -} -#endif - static bool parse_number(const struct shell *sh, long *param, char *str, char *pname, long min, long max) { @@ -1234,7 +954,7 @@ static int cmd_wifi_connect(const struct shell *sh, size_t argc, cnx_params.security == WIFI_SECURITY_TYPE_EAP_PEAP_GTC || cnx_params.security == WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2 || cnx_params.security == WIFI_SECURITY_TYPE_EAP_PEAP_TLS) { - wifi_set_enterprise_creds(sh, iface, 0); + wifi_set_enterprise_credentials(iface, 0); } #endif @@ -1278,7 +998,7 @@ static int cmd_wifi_disconnect(const struct shell *sh, size_t argc, #ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES /* Clear the certificates */ - clear_enterprise_creds_params(&context.enterprise_creds_params); + wifi_clear_enterprise_credentials(); #endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ return 0; @@ -1484,7 +1204,7 @@ static int cmd_wifi_status(const struct shell *sh, size_t argc, char *argv[]) PR("DTIM: %d\n", status.dtim_period); PR("TWT: %s\n", status.twt_capable ? "Supported" : "Not supported"); - PR("Current PHY TX rate (Mbps) : %d\n", status.current_phy_tx_rate); + PR("Current PHY TX rate (Mbps) : %.1f\n", (double)status.current_phy_tx_rate); } return 0; @@ -2291,7 +2011,7 @@ static int cmd_wifi_ap_disable(const struct shell *sh, size_t argc, #ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES /* Clear the certificates */ - clear_enterprise_creds_params(&context.enterprise_creds_params); + wifi_clear_enterprise_credentials(); #endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ return 0; @@ -3735,6 +3455,32 @@ static int cmd_wifi_pmksa_flush(const struct shell *sh, size_t argc, char *argv[ return 0; } + +static int cmd_wifi_set_bss_max_idle_period(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv); + unsigned short bss_max_idle_period = 0; + int idx = 1; + unsigned long val = 0; + + if (!parse_number(sh, &val, argv[idx++], "bss_max_idle_period", 0, USHRT_MAX)) { + return -EINVAL; + } + + bss_max_idle_period = (unsigned short)val; + + if (net_mgmt(NET_REQUEST_WIFI_BSS_MAX_IDLE_PERIOD, iface, + &bss_max_idle_period, sizeof(bss_max_idle_period))) { + shell_fprintf(sh, SHELL_WARNING, + "Setting BSS maximum idle period failed.\n"); + return -ENOEXEC; + } + + shell_fprintf(sh, SHELL_NORMAL, "BSS max idle period: %hu\n", bss_max_idle_period); + + return 0; +} + SHELL_STATIC_SUBCMD_SET_CREATE( wifi_cmd_ap, SHELL_CMD_ARG(disable, NULL, "Disable Access Point mode.\n" @@ -4210,6 +3956,12 @@ SHELL_SUBCMD_ADD((wifi), ps_exit_strategy, NULL, cmd_wifi_ps_exit_strategy, 2, 2); +SHELL_SUBCMD_ADD((wifi), bss_max_idle_period, NULL, + ".\n" + "[-i, --iface=] : Interface index.\n", + cmd_wifi_set_bss_max_idle_period, + 2, 2); + SHELL_CMD_REGISTER(wifi, &wifi_commands, "Wi-Fi commands", NULL); static int wifi_shell_init(void) diff --git a/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c b/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c index c5b8c2a88a3..3966a2404bc 100644 --- a/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c +++ b/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c @@ -22,247 +22,15 @@ #include +#ifdef CONFIG_WIFI_CERTIFICATE_LIB +#include +#endif + 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' -}; - -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_CREDENTIALS_RUNTIME_CERTIFICATES */ -#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ - -#if defined CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE -#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}; - -#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"); - return -1; - } - - return 0; -} -#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ - static void print_network_info(void *cb_arg, const char *ssid, size_t ssid_len) { int ret = 0; @@ -530,7 +298,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) { - wifi_set_enterprise_creds(sh, iface, 0); + wifi_set_enterprise_credentials(iface, 0); } #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ @@ -553,7 +321,7 @@ static int cmd_delete_network(const struct shell *sh, size_t argc, char *argv[]) #ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES /* Clear the certificates */ - clear_enterprise_creds_params(&enterprise_creds_params); + wifi_clear_enterprise_credentials(); #endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ return wifi_credentials_delete_by_ssid(argv[1], strlen(argv[1])); @@ -572,7 +340,7 @@ static int cmd_auto_connect(const struct shell *sh, size_t argc, char *argv[]) struct net_if *iface = net_if_get_wifi_sta(); #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE - wifi_set_enterprise_creds(sh, iface, 0); + wifi_set_enterprise_credentials(iface, 0); #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ int rc = net_mgmt(NET_REQUEST_WIFI_CONNECT_STORED, iface, NULL, 0); diff --git a/west.yml b/west.yml index d15e692caa4..56b80391830 100644 --- a/west.yml +++ b/west.yml @@ -281,7 +281,7 @@ manifest: - hal - name: hostap path: modules/lib/hostap - revision: e942f86e865d5b24bbbe8b0c333f030cbbe62bfb + revision: e7feee399bb6ebd185067e512873869c5556e24c - name: liblc3 revision: 48bbd3eacd36e99a57317a0a4867002e0b09e183 path: modules/lib/liblc3 @@ -328,7 +328,7 @@ manifest: revision: 968d55ff22579080466bf2f482596dd6e35361c6 path: modules/bsim_hw_models/nrf_hw_models - name: nrf_wifi - revision: 5f59c2336c69f28ae83f93812a1d726f9fceabfe + revision: 660071c36afa4c725c9b4922e4de466174bdf0e1 path: modules/lib/nrf_wifi - name: open-amp revision: f7f4d083c7909a39d86e217376c69b416ec4faf3