mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
Merge branch 'feature/softap_owe_support' into 'master'
Add support for OWE Only in SoftAP mode Closes WIFI-4281 and IDFGH-12437 See merge request espressif/esp-idf!47341
This commit is contained in:
@@ -346,6 +346,14 @@ menu "Wi-Fi"
|
|||||||
help
|
help
|
||||||
Select this option to support wpa3_compatible mode for station and AP
|
Select this option to support wpa3_compatible mode for station and AP
|
||||||
|
|
||||||
|
config ESP_WIFI_ENABLE_WPA3_OWE_SOFTAP
|
||||||
|
bool "Enable OWE-ONLY SOFTAP"
|
||||||
|
default y
|
||||||
|
select ESP_WIFI_MBEDTLS_CRYPTO
|
||||||
|
depends on ESP_WIFI_SOFTAP_SUPPORT
|
||||||
|
help
|
||||||
|
Select this option to allow the device to enable OWE Only mode for softap.
|
||||||
|
|
||||||
config ESP_WIFI_SLP_IRAM_OPT
|
config ESP_WIFI_SLP_IRAM_OPT
|
||||||
bool "WiFi SLP IRAM speed optimization"
|
bool "WiFi SLP IRAM speed optimization"
|
||||||
select PM_SLP_DEFAULT_PARAMS_OPT
|
select PM_SLP_DEFAULT_PARAMS_OPT
|
||||||
|
|||||||
@@ -290,6 +290,12 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs;
|
|||||||
#define WIFI_ENABLE_PASSIVE_HIDDEN_AP 0
|
#define WIFI_ENABLE_PASSIVE_HIDDEN_AP 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_SOFTAP
|
||||||
|
#define WIFI_ENABLE_OWE_SOFTAP (1<<10)
|
||||||
|
#else
|
||||||
|
#define WIFI_ENABLE_OWE_SOFTAP 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CONFIG_FEATURE_WPA3_SAE_BIT (1<<0)
|
#define CONFIG_FEATURE_WPA3_SAE_BIT (1<<0)
|
||||||
#define CONFIG_FEATURE_CACHE_TX_BUF_BIT (1<<1)
|
#define CONFIG_FEATURE_CACHE_TX_BUF_BIT (1<<1)
|
||||||
#define CONFIG_FEATURE_FTM_INITIATOR_BIT (1<<2)
|
#define CONFIG_FEATURE_FTM_INITIATOR_BIT (1<<2)
|
||||||
@@ -300,6 +306,7 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs;
|
|||||||
#define CONFIG_FEATURE_WIFI_ENT_BIT (1<<7)
|
#define CONFIG_FEATURE_WIFI_ENT_BIT (1<<7)
|
||||||
#define CONFIG_FEATURE_BSS_MAX_IDLE_BIT (1<<8)
|
#define CONFIG_FEATURE_BSS_MAX_IDLE_BIT (1<<8)
|
||||||
#define CONFIG_FEATURE_WIFI_PASSIVE_HIDDEN_AP_BIT (1<<9)
|
#define CONFIG_FEATURE_WIFI_PASSIVE_HIDDEN_AP_BIT (1<<9)
|
||||||
|
#define CONFIG_FEATURE_OWE_SOFTAP_BIT (1<<10)
|
||||||
|
|
||||||
/* Set additional WiFi features and capabilities */
|
/* Set additional WiFi features and capabilities */
|
||||||
#define WIFI_FEATURE_CAPS (WIFI_ENABLE_WPA3_SAE | \
|
#define WIFI_FEATURE_CAPS (WIFI_ENABLE_WPA3_SAE | \
|
||||||
@@ -311,7 +318,8 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs;
|
|||||||
WIFI_ENABLE_11R | \
|
WIFI_ENABLE_11R | \
|
||||||
WIFI_ENABLE_ENTERPRISE | \
|
WIFI_ENABLE_ENTERPRISE | \
|
||||||
WIFI_ENABLE_BSS_MAX_IDLE | \
|
WIFI_ENABLE_BSS_MAX_IDLE | \
|
||||||
WIFI_ENABLE_PASSIVE_HIDDEN_AP)
|
WIFI_ENABLE_PASSIVE_HIDDEN_AP | \
|
||||||
|
WIFI_ENABLE_OWE_SOFTAP)
|
||||||
|
|
||||||
#define WIFI_INIT_CONFIG_DEFAULT() { \
|
#define WIFI_INIT_CONFIG_DEFAULT() { \
|
||||||
.osi_funcs = &g_wifi_osi_funcs, \
|
.osi_funcs = &g_wifi_osi_funcs, \
|
||||||
|
|||||||
+1
-1
Submodule components/esp_wifi/lib updated: 5bc1b23488...694f70f614
@@ -325,6 +325,14 @@ config WIFI_RMT_WPA3_COMPATIBLE_SUPPORT
|
|||||||
help
|
help
|
||||||
Select this option to support wpa3_compatible mode for station and AP
|
Select this option to support wpa3_compatible mode for station and AP
|
||||||
|
|
||||||
|
config WIFI_RMT_ENABLE_WPA3_OWE_SOFTAP
|
||||||
|
bool "Enable OWE-ONLY SOFTAP"
|
||||||
|
default y
|
||||||
|
select WIFI_RMT_MBEDTLS_CRYPTO
|
||||||
|
depends on WIFI_RMT_SOFTAP_SUPPORT
|
||||||
|
help
|
||||||
|
Select this option to allow the device to enable OWE Only mode for softap.
|
||||||
|
|
||||||
config WIFI_RMT_SLP_IRAM_OPT
|
config WIFI_RMT_SLP_IRAM_OPT
|
||||||
bool "WiFi SLP IRAM speed optimization"
|
bool "WiFi SLP IRAM speed optimization"
|
||||||
select PM_SLP_DEFAULT_PARAMS_OPT
|
select PM_SLP_DEFAULT_PARAMS_OPT
|
||||||
|
|||||||
@@ -142,6 +142,13 @@ if WIFI_RMT_WPA3_COMPATIBLE_SUPPORT
|
|||||||
default WIFI_RMT_WPA3_COMPATIBLE_SUPPORT
|
default WIFI_RMT_WPA3_COMPATIBLE_SUPPORT
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if WIFI_RMT_ENABLE_WPA3_OWE_SOFTAP
|
||||||
|
config ESP_WIFI_ENABLE_WPA3_OWE_SOFTAP # ignore: multiple-definition
|
||||||
|
bool
|
||||||
|
depends on WIFI_RMT_SOFTAP_SUPPORT
|
||||||
|
default WIFI_RMT_ENABLE_WPA3_OWE_SOFTAP
|
||||||
|
endif
|
||||||
|
|
||||||
if WIFI_RMT_SLP_IRAM_OPT
|
if WIFI_RMT_SLP_IRAM_OPT
|
||||||
config ESP_WIFI_SLP_IRAM_OPT # ignore: multiple-definition
|
config ESP_WIFI_SLP_IRAM_OPT # ignore: multiple-definition
|
||||||
bool
|
bool
|
||||||
|
|||||||
@@ -290,6 +290,12 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs;
|
|||||||
#define WIFI_ENABLE_PASSIVE_HIDDEN_AP 0
|
#define WIFI_ENABLE_PASSIVE_HIDDEN_AP 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_WIFI_RMT_ENABLE_WPA3_OWE_SOFTAP
|
||||||
|
#define WIFI_ENABLE_OWE_SOFTAP (1<<10)
|
||||||
|
#else
|
||||||
|
#define WIFI_ENABLE_OWE_SOFTAP 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CONFIG_FEATURE_WPA3_SAE_BIT (1<<0)
|
#define CONFIG_FEATURE_WPA3_SAE_BIT (1<<0)
|
||||||
#define CONFIG_FEATURE_CACHE_TX_BUF_BIT (1<<1)
|
#define CONFIG_FEATURE_CACHE_TX_BUF_BIT (1<<1)
|
||||||
#define CONFIG_FEATURE_FTM_INITIATOR_BIT (1<<2)
|
#define CONFIG_FEATURE_FTM_INITIATOR_BIT (1<<2)
|
||||||
@@ -300,6 +306,7 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs;
|
|||||||
#define CONFIG_FEATURE_WIFI_ENT_BIT (1<<7)
|
#define CONFIG_FEATURE_WIFI_ENT_BIT (1<<7)
|
||||||
#define CONFIG_FEATURE_BSS_MAX_IDLE_BIT (1<<8)
|
#define CONFIG_FEATURE_BSS_MAX_IDLE_BIT (1<<8)
|
||||||
#define CONFIG_FEATURE_WIFI_PASSIVE_HIDDEN_AP_BIT (1<<9)
|
#define CONFIG_FEATURE_WIFI_PASSIVE_HIDDEN_AP_BIT (1<<9)
|
||||||
|
#define CONFIG_FEATURE_OWE_SOFTAP_BIT (1<<10)
|
||||||
|
|
||||||
/* Set additional WiFi features and capabilities */
|
/* Set additional WiFi features and capabilities */
|
||||||
#define WIFI_FEATURE_CAPS (WIFI_ENABLE_WPA3_SAE | \
|
#define WIFI_FEATURE_CAPS (WIFI_ENABLE_WPA3_SAE | \
|
||||||
@@ -311,7 +318,8 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs;
|
|||||||
WIFI_ENABLE_11R | \
|
WIFI_ENABLE_11R | \
|
||||||
WIFI_ENABLE_ENTERPRISE | \
|
WIFI_ENABLE_ENTERPRISE | \
|
||||||
WIFI_ENABLE_BSS_MAX_IDLE | \
|
WIFI_ENABLE_BSS_MAX_IDLE | \
|
||||||
WIFI_ENABLE_PASSIVE_HIDDEN_AP)
|
WIFI_ENABLE_PASSIVE_HIDDEN_AP | \
|
||||||
|
WIFI_ENABLE_OWE_SOFTAP)
|
||||||
|
|
||||||
#define WIFI_INIT_CONFIG_DEFAULT() { \
|
#define WIFI_INIT_CONFIG_DEFAULT() { \
|
||||||
.osi_funcs = &g_wifi_osi_funcs, \
|
.osi_funcs = &g_wifi_osi_funcs, \
|
||||||
|
|||||||
@@ -362,4 +362,7 @@ endif()
|
|||||||
if(CONFIG_ESP_WIFI_NAN_USD_ENABLE)
|
if(CONFIG_ESP_WIFI_NAN_USD_ENABLE)
|
||||||
target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_NAN_USD)
|
target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_NAN_USD)
|
||||||
endif()
|
endif()
|
||||||
|
if(CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_SOFTAP)
|
||||||
|
target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_OWE_SOFTAP)
|
||||||
|
endif()
|
||||||
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY LINK_INTERFACE_MULTIPLICITY 3)
|
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY LINK_INTERFACE_MULTIPLICITY 3)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2019-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -28,6 +28,12 @@
|
|||||||
#include "ap/ieee802_11.h"
|
#include "ap/ieee802_11.h"
|
||||||
#define WIFI_PASSWORD_LEN_MAX 65
|
#define WIFI_PASSWORD_LEN_MAX 65
|
||||||
|
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
#include "crypto/crypto.h"
|
||||||
|
#include "ap/ieee802_11.h"
|
||||||
|
#include "esp_owe_i.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
struct hostapd_data *global_hapd;
|
struct hostapd_data *global_hapd;
|
||||||
|
|
||||||
#ifdef CONFIG_SAE
|
#ifdef CONFIG_SAE
|
||||||
@@ -48,7 +54,8 @@ static bool authmode_has_rsn(uint8_t authmode)
|
|||||||
return (authmode == WIFI_AUTH_WPA2_PSK ||
|
return (authmode == WIFI_AUTH_WPA2_PSK ||
|
||||||
authmode == WIFI_AUTH_WPA_WPA2_PSK ||
|
authmode == WIFI_AUTH_WPA_WPA2_PSK ||
|
||||||
authmode == WIFI_AUTH_WPA3_PSK ||
|
authmode == WIFI_AUTH_WPA3_PSK ||
|
||||||
authmode == WIFI_AUTH_WPA2_WPA3_PSK);
|
authmode == WIFI_AUTH_WPA2_WPA3_PSK ||
|
||||||
|
authmode == WIFI_AUTH_OWE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *hostap_init(void)
|
void *hostap_init(void)
|
||||||
@@ -192,6 +199,13 @@ void *hostap_init(void)
|
|||||||
|
|
||||||
#endif /* CONFIG_IEEE80211W */
|
#endif /* CONFIG_IEEE80211W */
|
||||||
esp_wifi_ap_set_group_mgmt_cipher_internal(cipher_type_map_supp_to_public(auth_conf->group_mgmt_cipher));
|
esp_wifi_ap_set_group_mgmt_cipher_internal(cipher_type_map_supp_to_public(auth_conf->group_mgmt_cipher));
|
||||||
|
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
if (authmode == WIFI_AUTH_OWE) {
|
||||||
|
auth_conf->wpa_key_mgmt = WPA_KEY_MGMT_OWE;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_OWE_SOFTAP */
|
||||||
|
|
||||||
spp_attrubute = esp_wifi_get_spp_attrubute_internal(WIFI_IF_AP);
|
spp_attrubute = esp_wifi_get_spp_attrubute_internal(WIFI_IF_AP);
|
||||||
auth_conf->spp_sup.capable = ((spp_attrubute & WPA_CAPABILITY_SPP_CAPABLE) ? SPP_AMSDU_CAP_ENABLE : SPP_AMSDU_CAP_DISABLE);
|
auth_conf->spp_sup.capable = ((spp_attrubute & WPA_CAPABILITY_SPP_CAPABLE) ? SPP_AMSDU_CAP_ENABLE : SPP_AMSDU_CAP_DISABLE);
|
||||||
auth_conf->spp_sup.require = ((spp_attrubute & WPA_CAPABILITY_SPP_REQUIRED) ? SPP_AMSDU_REQ_ENABLE : SPP_AMSDU_REQ_DISABLE);
|
auth_conf->spp_sup.require = ((spp_attrubute & WPA_CAPABILITY_SPP_REQUIRED) ? SPP_AMSDU_REQ_ENABLE : SPP_AMSDU_REQ_DISABLE);
|
||||||
@@ -365,14 +379,35 @@ u16 esp_send_assoc_resp(struct hostapd_data *hapd, const u8 *addr,
|
|||||||
u8 buf[ASSOC_RESP_LENGTH];
|
u8 buf[ASSOC_RESP_LENGTH];
|
||||||
wifi_mgmt_frm_req_t *reply = NULL;
|
wifi_mgmt_frm_req_t *reply = NULL;
|
||||||
int send_len = 0;
|
int send_len = 0;
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
const bool owe_resp = (status_code == WLAN_STATUS_SUCCESS) &&
|
||||||
|
(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
|
||||||
|
esp_wifi_ap_get_owe_config_internal();
|
||||||
|
#else
|
||||||
|
const bool owe_resp = false;
|
||||||
|
#endif
|
||||||
int res = WLAN_STATUS_SUCCESS;
|
int res = WLAN_STATUS_SUCCESS;
|
||||||
|
|
||||||
if (!omit_rsnxe) {
|
if (!omit_rsnxe && !owe_resp) {
|
||||||
send_len = esp_wifi_build_rsnxe(hapd, buf, ASSOC_RESP_LENGTH);
|
send_len = esp_wifi_build_rsnxe(hapd, buf, ASSOC_RESP_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!owe_resp) {
|
||||||
esp_wifi_set_appie_internal(WIFI_APPIE_ASSOC_RESP, buf, send_len, 0);
|
esp_wifi_set_appie_internal(WIFI_APPIE_ASSOC_RESP, buf, send_len, 0);
|
||||||
|
}
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
if (owe_resp) {
|
||||||
|
int owe_ie_len = 0;
|
||||||
|
struct wpabuf *owe_ie = esp_owe_build_assoc_resp_dhie(hapd, addr, &owe_ie_len);
|
||||||
|
if (owe_ie_len <= 0 || !owe_ie) {
|
||||||
|
wpa_printf(MSG_ERROR, "%s : error creating dhie for assoc resp %d ", __func__, owe_ie_len);
|
||||||
|
wpabuf_free(owe_ie);
|
||||||
|
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
}
|
||||||
|
esp_wifi_set_appie_internal(WIFI_APPIE_ASSOC_RESP, (uint8_t *)wpabuf_head(owe_ie), owe_ie_len, 0);
|
||||||
|
wpabuf_free(owe_ie);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_OWE_SOFTAP */
|
||||||
|
|
||||||
reply = os_zalloc(sizeof(wifi_mgmt_frm_req_t) + sizeof(uint16_t));
|
reply = os_zalloc(sizeof(wifi_mgmt_frm_req_t) + sizeof(uint16_t));
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
@@ -416,9 +451,9 @@ uint8_t wpa_status_to_reason_code(int status)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, u8 *wpa_ie,
|
bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid,
|
||||||
u8 wpa_ie_len, u8 *rsnxe, uint16_t rsnxe_len,
|
const struct hostap_assoc_sta_req *assoc_req,
|
||||||
bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason, uint8_t *rsn_selection_ie)
|
bool *pmf_enable, u8 *pairwise_cipher, u8 *reason)
|
||||||
{
|
{
|
||||||
struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal();
|
struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal();
|
||||||
enum wpa_validate_result res = WPA_IE_OK;
|
enum wpa_validate_result res = WPA_IE_OK;
|
||||||
@@ -430,7 +465,7 @@ bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, u8 *wpa_ie,
|
|||||||
uint8_t *rsn_selection_variant_ie = NULL;
|
uint8_t *rsn_selection_variant_ie = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!sta || !bssid || !wpa_ie) {
|
if (!sta || !bssid || !assoc_req || !assoc_req->wpa_ie) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (hapd) {
|
if (hapd) {
|
||||||
@@ -449,15 +484,16 @@ bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, u8 *wpa_ie,
|
|||||||
|
|
||||||
#ifdef CONFIG_WPA3_COMPAT
|
#ifdef CONFIG_WPA3_COMPAT
|
||||||
#define RSN_SELECTION_IE_OUI_LEN 4
|
#define RSN_SELECTION_IE_OUI_LEN 4
|
||||||
if (rsn_selection_ie) {
|
if (assoc_req->rsn_selection_ie) {
|
||||||
rsn_selection_variant_len = rsn_selection_ie[1] - RSN_SELECTION_IE_OUI_LEN;
|
rsn_selection_variant_len = assoc_req->rsn_selection_ie[1] - RSN_SELECTION_IE_OUI_LEN;
|
||||||
rsn_selection_variant_ie = &rsn_selection_ie[RSN_SELECTION_IE_OUI_LEN + 2];
|
rsn_selection_variant_ie = &assoc_req->rsn_selection_ie[RSN_SELECTION_IE_OUI_LEN + 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_auth_set_rsn_selection(sta->wpa_sm, rsn_selection_variant_ie, rsn_selection_variant_len);
|
wpa_auth_set_rsn_selection(sta->wpa_sm, rsn_selection_variant_ie, rsn_selection_variant_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len);
|
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, assoc_req->wpa_ie,
|
||||||
|
assoc_req->wpa_ie_len, assoc_req->rsnxe, assoc_req->rsnxe_len);
|
||||||
#ifdef CONFIG_SAE
|
#ifdef CONFIG_SAE
|
||||||
if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae &&
|
if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae &&
|
||||||
sta->sae->state == SAE_ACCEPTED) {
|
sta->sae->state == SAE_ACCEPTED) {
|
||||||
@@ -468,8 +504,30 @@ bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, u8 *wpa_ie,
|
|||||||
|
|
||||||
status = wpa_res_to_status_code(res);
|
status = wpa_res_to_status_code(res);
|
||||||
|
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
uint8_t owe_enabled = esp_wifi_ap_get_owe_config_internal();
|
||||||
|
if (status == WLAN_STATUS_SUCCESS &&
|
||||||
|
(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
|
||||||
|
sta->wpa_sm->wpa_key_mgmt == WPA_KEY_MGMT_OWE &&
|
||||||
|
owe_enabled) {
|
||||||
|
if (!assoc_req->owe_dh || assoc_req->owe_ie_len == 0) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"OWE: Association request missing DH Parameter element");
|
||||||
|
status = WLAN_STATUS_AKMP_NOT_VALID;
|
||||||
|
} else {
|
||||||
|
status = owe_process_assoc_req(hapd, sta, assoc_req->owe_dh,
|
||||||
|
assoc_req->owe_ie_len);
|
||||||
|
if (status != WLAN_STATUS_SUCCESS) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"OWE: Failed to process assoc req status %d",
|
||||||
|
status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_OWE_SOFTAP */
|
||||||
|
|
||||||
send_resp:
|
send_resp:
|
||||||
if (!rsnxe) {
|
if (!assoc_req->rsnxe) {
|
||||||
omit_rsnxe = true;
|
omit_rsnxe = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,7 +537,7 @@ send_resp:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (esp_send_assoc_resp(hapd, bssid, status, omit_rsnxe, subtype) != WLAN_STATUS_SUCCESS) {
|
if (esp_send_assoc_resp(hapd, bssid, status, omit_rsnxe, assoc_req->subtype) != WLAN_STATUS_SUCCESS) {
|
||||||
status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
|
status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,22 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_OWE_STA
|
|
||||||
|
|
||||||
#include "crypto/crypto.h"
|
#include "crypto/crypto.h"
|
||||||
#include "esp_owe_i.h"
|
#include "esp_owe_i.h"
|
||||||
#include "rsn_supp/wpa.h"
|
#include "rsn_supp/wpa.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
#include "ap/hostapd.h"
|
||||||
|
#include "ap/sta_info.h"
|
||||||
|
#include "ap/wpa_auth.h"
|
||||||
|
#include "ap/wpa_auth_i.h"
|
||||||
|
#include "common/ieee802_11_defs.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_OWE_STA
|
||||||
uint8_t *owe_build_dhie(uint16_t group)
|
uint8_t *owe_build_dhie(uint16_t group)
|
||||||
{
|
{
|
||||||
struct wpa_sm *sm = NULL;
|
struct wpa_sm *sm = NULL;
|
||||||
@@ -36,3 +44,100 @@ void esp_wifi_register_owe_cb(struct wpa_funcs *wpa_cb)
|
|||||||
wpa_cb->owe_process_assoc_resp = owe_process_assoc_resp;
|
wpa_cb->owe_process_assoc_resp = owe_process_assoc_resp;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_OWE_STA */
|
#endif /* CONFIG_OWE_STA */
|
||||||
|
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
struct wpabuf *esp_owe_build_assoc_resp_dhie(struct hostapd_data *hapd, const u8 *bssid, int *owe_ie_len)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!hapd || !hapd->wpa_auth || !hapd->wpa_auth->wpa_ie) {
|
||||||
|
wpa_printf(MSG_ERROR, "Invalid hapd or WPA auth data");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wpabuf *pub;
|
||||||
|
struct sta_info *sta = ap_get_sta(hapd, bssid);
|
||||||
|
if (!sta) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wpabuf *owe_buf = wpabuf_alloc(OWE_IE_INIT_LEN);
|
||||||
|
if (!owe_buf) {
|
||||||
|
wpa_printf(MSG_ERROR, "Memory allocation failed for OWE IE");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If PMKSA caching is used, write and return only RSN IE with PMKID
|
||||||
|
if (sta->wpa_sm && sta->wpa_sm->pmksa) {
|
||||||
|
u8 *pos, buf[257];
|
||||||
|
pos = buf;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "OWE: Using PMKSA caching for Assoc Resp");
|
||||||
|
pos = wpa_auth_write_assoc_resp_owe(hapd, sta->wpa_sm, pos,
|
||||||
|
buf + sizeof(buf) - pos);
|
||||||
|
|
||||||
|
if (wpabuf_resize(&owe_buf, pos - buf) < 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "OWE: wpabuf_resize failed for PMKSA assoc resp");
|
||||||
|
wpabuf_free(owe_buf);
|
||||||
|
*owe_ie_len = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
wpabuf_put_data(owe_buf, buf, pos - buf);
|
||||||
|
*owe_ie_len = pos - buf;
|
||||||
|
return owe_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sta->owe_ecdh) {
|
||||||
|
if (!sta->wpa_sm) {
|
||||||
|
wpa_printf(MSG_ERROR, "OWE: Missing WPA state machine for assoc resp");
|
||||||
|
wpabuf_free(owe_buf);
|
||||||
|
*owe_ie_len = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 buf[257];
|
||||||
|
u8 *pos = buf;
|
||||||
|
|
||||||
|
pos = wpa_auth_write_assoc_resp_owe(hapd, sta->wpa_sm, pos,
|
||||||
|
buf + sizeof(buf) - pos);
|
||||||
|
size_t rsne_len = (size_t)(pos - buf);
|
||||||
|
|
||||||
|
if (rsne_len == 0 || pos > buf + sizeof(buf)) {
|
||||||
|
wpa_printf(MSG_ERROR, "OWE: Failed to write RSN IE for assoc resp");
|
||||||
|
wpabuf_free(owe_buf);
|
||||||
|
*owe_ie_len = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
|
||||||
|
if (!pub) {
|
||||||
|
wpabuf_free(owe_buf);
|
||||||
|
*owe_ie_len = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump_buf(MSG_DEBUG, "Own public key", pub);
|
||||||
|
|
||||||
|
size_t dh_len = 5 + wpabuf_len(pub);
|
||||||
|
|
||||||
|
if (wpabuf_resize(&owe_buf, rsne_len + dh_len) < 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "OWE: wpabuf_resize failed for assoc resp IEs");
|
||||||
|
wpabuf_free(pub);
|
||||||
|
wpabuf_free(owe_buf);
|
||||||
|
*owe_ie_len = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
wpabuf_put_data(owe_buf, buf, rsne_len);
|
||||||
|
wpabuf_put_u8(owe_buf, WLAN_EID_EXTENSION);
|
||||||
|
wpabuf_put_u8(owe_buf, 1 + 2 + wpabuf_len(pub));
|
||||||
|
wpabuf_put_u8(owe_buf, WLAN_EID_EXT_OWE_DH_PARAM);
|
||||||
|
wpabuf_put_le16(owe_buf, IANA_SECP256R1);
|
||||||
|
wpabuf_put_buf(owe_buf, pub);
|
||||||
|
wpabuf_free(pub);
|
||||||
|
|
||||||
|
wpa_hexdump_buf(MSG_DEBUG, "OWE: Buffer", owe_buf);
|
||||||
|
}
|
||||||
|
*owe_ie_len = wpabuf_len(owe_buf);
|
||||||
|
|
||||||
|
return owe_buf;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_OWE_SOFTAP */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -20,4 +20,26 @@ void owe_deinit(void);
|
|||||||
void esp_wifi_register_owe_cb(struct wpa_funcs *wpa_cb);
|
void esp_wifi_register_owe_cb(struct wpa_funcs *wpa_cb);
|
||||||
|
|
||||||
#endif /* CONFIG_OWE_STA */
|
#endif /* CONFIG_OWE_STA */
|
||||||
|
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
|
||||||
|
#include "ap/hostapd.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OWE_DHIE_LEN: DH Parameter element length for group 19 (secp256r1).
|
||||||
|
*
|
||||||
|
* Wire format (IEEE 802.11 Extension element):
|
||||||
|
* byte 1 WLAN_EID_EXTENSION
|
||||||
|
* byte 2 length of remainder (extension ID + group + pubkey), typically 35
|
||||||
|
* byte 3 WLAN_EID_EXT_OWE_DH_PARAM (extension element ID)
|
||||||
|
* bytes 4–5 DH group ID (little-endian), e.g. IANA_SECP256R1 (19)
|
||||||
|
* bytes 6–37 DH public key (32 octets for this group/key representation)
|
||||||
|
*
|
||||||
|
* Total = 2 + 35 = 37 octets.
|
||||||
|
*/
|
||||||
|
#define OWE_DHIE_LEN 37
|
||||||
|
#define OWE_IE_INIT_LEN (257 + OWE_DHIE_LEN) /* RSNE + DH IE */
|
||||||
|
struct wpabuf *esp_owe_build_assoc_resp_dhie(struct hostapd_data *hapd, const u8 *bssid, int *owe_ie_len);
|
||||||
|
|
||||||
|
#endif /* CONFIG_OWE_SOFTAP */
|
||||||
#endif /* ESP_OWE_H */
|
#endif /* ESP_OWE_H */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2019-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -120,6 +120,21 @@ typedef struct {
|
|||||||
uint8_t rsnxe_capa;
|
uint8_t rsnxe_capa;
|
||||||
} wifi_wpa_ie_t;
|
} wifi_wpa_ie_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void **sm;
|
||||||
|
u8 *bssid;
|
||||||
|
u8 *wpa_ie;
|
||||||
|
u8 *rsnxe;
|
||||||
|
bool *pmf_enable;
|
||||||
|
uint8_t *pairwise_cipher;
|
||||||
|
uint8_t *rsn_selection_ie;
|
||||||
|
uint8_t *owe_dhie;
|
||||||
|
int subtype;
|
||||||
|
u16 rsnxe_len;
|
||||||
|
u8 wpa_ie_len;
|
||||||
|
u8 owe_dh_len;
|
||||||
|
} wpa_station_join_param_t;
|
||||||
|
|
||||||
struct wpa_funcs {
|
struct wpa_funcs {
|
||||||
bool (*wpa_sta_init)(void);
|
bool (*wpa_sta_init)(void);
|
||||||
bool (*wpa_sta_deinit)(void);
|
bool (*wpa_sta_deinit)(void);
|
||||||
@@ -130,7 +145,7 @@ struct wpa_funcs {
|
|||||||
bool (*wpa_sta_in_4way_handshake)(void);
|
bool (*wpa_sta_in_4way_handshake)(void);
|
||||||
void *(*wpa_ap_init)(void);
|
void *(*wpa_ap_init)(void);
|
||||||
bool (*wpa_ap_deinit)(void *data);
|
bool (*wpa_ap_deinit)(void *data);
|
||||||
bool (*wpa_ap_join)(void **sm, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, u8* rsnxe, u16 rsnxe_len, bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *rsn_selection_ie);
|
bool (*wpa_ap_join)(wpa_station_join_param_t *join);
|
||||||
bool (*wpa_ap_remove)(u8 *bssid);
|
bool (*wpa_ap_remove)(u8 *bssid);
|
||||||
uint8_t *(*wpa_ap_get_wpa_ie)(size_t *len);
|
uint8_t *(*wpa_ap_get_wpa_ie)(size_t *len);
|
||||||
bool (*wpa_ap_rx_eapol)(void *hapd_data, void *sm, u8 *data, size_t data_len);
|
bool (*wpa_ap_rx_eapol)(void *hapd_data, void *sm, u8 *data, size_t data_len);
|
||||||
@@ -312,4 +327,6 @@ void esp_wifi_set_sigma_internal(bool flag);
|
|||||||
void esp_wifi_ap_set_group_mgmt_cipher_internal(wifi_cipher_type_t cipher);
|
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);
|
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);
|
bool esp_wifi_is_wpa3_compatible_mode_enabled(uint8_t if_index);
|
||||||
|
uint8_t esp_wifi_ap_get_owe_config_internal(void);
|
||||||
|
|
||||||
#endif /* _ESP_WIFI_DRIVER_H_ */
|
#endif /* _ESP_WIFI_DRIVER_H_ */
|
||||||
|
|||||||
@@ -389,12 +389,29 @@ static int check_n_add_wps_sta(struct hostapd_data *hapd, struct sta_info *sta_i
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, u8 *rsnxe, u16 rsnxe_len, bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *rsn_selection_ie)
|
static bool hostap_sta_join(wpa_station_join_param_t *join)
|
||||||
{
|
{
|
||||||
struct sta_info *sta_info = NULL;
|
struct sta_info *sta_info = NULL;
|
||||||
struct hostapd_data *hapd = hostapd_get_hapd_data();
|
struct hostapd_data *hapd = hostapd_get_hapd_data();
|
||||||
uint8_t reason = WLAN_REASON_PREV_AUTH_NOT_VALID;
|
uint8_t reason = WLAN_REASON_PREV_AUTH_NOT_VALID;
|
||||||
|
|
||||||
|
if (!join) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void **sta = join->sm;
|
||||||
|
u8 *bssid = join->bssid;
|
||||||
|
u8 *wpa_ie = join->wpa_ie;
|
||||||
|
u8 *rsnxe = join->rsnxe;
|
||||||
|
bool *pmf_enable = join->pmf_enable;
|
||||||
|
uint8_t *pairwise_cipher = join->pairwise_cipher;
|
||||||
|
uint8_t *rsn_selection_ie = join->rsn_selection_ie;
|
||||||
|
uint8_t *owe_dhie = join->owe_dhie;
|
||||||
|
int subtype = join->subtype;
|
||||||
|
u16 rsnxe_len = join->rsnxe_len;
|
||||||
|
u8 wpa_ie_len = join->wpa_ie_len;
|
||||||
|
u8 owe_dh_len = join->owe_dh_len;
|
||||||
|
|
||||||
if (!hapd) {
|
if (!hapd) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@@ -451,7 +468,19 @@ process_old_sta:
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (hostap_new_assoc_sta(sta_info, bssid, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len, pmf_enable, subtype, pairwise_cipher, &reason, rsn_selection_ie)) {
|
|
||||||
|
struct hostap_assoc_sta_req assoc_req = {
|
||||||
|
.wpa_ie = wpa_ie,
|
||||||
|
.wpa_ie_len = wpa_ie_len,
|
||||||
|
.rsnxe = rsnxe,
|
||||||
|
.rsnxe_len = rsnxe_len,
|
||||||
|
.subtype = subtype,
|
||||||
|
.rsn_selection_ie = rsn_selection_ie,
|
||||||
|
.owe_dh = owe_dhie,
|
||||||
|
.owe_ie_len = owe_dh_len,
|
||||||
|
};
|
||||||
|
if (hostap_new_assoc_sta(sta_info, bssid, &assoc_req, pmf_enable,
|
||||||
|
pairwise_cipher, &reason)) {
|
||||||
goto done;
|
goto done;
|
||||||
} else {
|
} else {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|||||||
@@ -395,9 +395,21 @@ const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
|
|||||||
const u8 *addr, const u8 *prev_psk);
|
const u8 *addr, const u8 *prev_psk);
|
||||||
int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf);
|
int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf);
|
||||||
struct sta_info;
|
struct sta_info;
|
||||||
bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, u8 *wpa_ie,
|
|
||||||
u8 wpa_ie_len, u8 *rsnxe, uint16_t rsnxe_len,
|
struct hostap_assoc_sta_req {
|
||||||
bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason, uint8_t *rsn_selection_ie);
|
u8 *wpa_ie;
|
||||||
|
u8 wpa_ie_len;
|
||||||
|
u8 *rsnxe;
|
||||||
|
u16 rsnxe_len;
|
||||||
|
int subtype;
|
||||||
|
u8 *rsn_selection_ie;
|
||||||
|
u8 *owe_dh;
|
||||||
|
u8 owe_ie_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid,
|
||||||
|
const struct hostap_assoc_sta_req *assoc_req,
|
||||||
|
bool *pmf_enable, u8 *pairwise_cipher, u8 *reason);
|
||||||
bool wpa_ap_remove(u8* bssid);
|
bool wpa_ap_remove(u8* bssid);
|
||||||
|
|
||||||
#endif /* HOSTAPD_CONFIG_H */
|
#endif /* HOSTAPD_CONFIG_H */
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "utils/includes.h"
|
#include "utils/includes.h"
|
||||||
|
#include "utils/common.h"
|
||||||
#include "common/sae.h"
|
#include "common/sae.h"
|
||||||
#include "common/ieee802_11_defs.h"
|
#include "common/ieee802_11_defs.h"
|
||||||
#include "esp_wifi_driver.h"
|
#include "esp_wifi_driver.h"
|
||||||
@@ -20,6 +21,13 @@
|
|||||||
#include "esp_wpa3_i.h"
|
#include "esp_wpa3_i.h"
|
||||||
#include "esp_hostap.h"
|
#include "esp_hostap.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
#include "crypto/crypto.h"
|
||||||
|
#include "ap/wpa_auth_i.h"
|
||||||
|
#include "esp_owe_i.h"
|
||||||
|
#define OWE_DH_GRP19 19
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SAE
|
#ifdef CONFIG_SAE
|
||||||
|
|
||||||
static void sae_set_state(struct sta_info *sta, enum sae_state state,
|
static void sae_set_state(struct sta_info *sta, enum sae_state state,
|
||||||
@@ -773,3 +781,183 @@ u16 wpa_res_to_status_code(enum wpa_validate_result res)
|
|||||||
}
|
}
|
||||||
return WLAN_STATUS_INVALID_IE;
|
return WLAN_STATUS_INVALID_IE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
|
||||||
|
int wpa_auth_pmksa_add2(struct wpa_authenticator *wpa_auth, const u8 *addr,
|
||||||
|
const u8 *pmk, size_t pmk_len, const u8 *pmkid,
|
||||||
|
int session_timeout, int akmp, const u8 *dpp_pkhash)
|
||||||
|
{
|
||||||
|
if (!wpa_auth || wpa_auth->conf.disable_pmksa_caching)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
struct rsn_pmksa_cache_entry *entry;
|
||||||
|
|
||||||
|
wpa_hexdump_key(MSG_DEBUG, "RSN: Cache PMK (3)", pmk, pmk_len);
|
||||||
|
entry = pmksa_cache_auth_add(wpa_auth->pmksa, pmk, pmk_len, pmkid,
|
||||||
|
NULL, 0, wpa_auth->addr, addr, session_timeout,
|
||||||
|
NULL, akmp);
|
||||||
|
if (!entry)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t owe_process_assoc_req(struct hostapd_data *hapd, struct sta_info *sta, const u8 *owe_dh,
|
||||||
|
u8 owe_dh_len)
|
||||||
|
{
|
||||||
|
const u8 *addr[2];
|
||||||
|
size_t len[2];
|
||||||
|
struct wpabuf *hkey, *pub, *secret;
|
||||||
|
const char *info = "OWE Key Generation";
|
||||||
|
u8 prk[SHA256_MAC_LEN];
|
||||||
|
u8 pmkid[SHA256_MAC_LEN];
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (wpa_auth_sta_get_pmksa(sta->wpa_sm)) {
|
||||||
|
wpa_printf(MSG_DEBUG, "OWE: Using PMKSA caching");
|
||||||
|
return WLAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!owe_dh || owe_dh_len < 5) {
|
||||||
|
wpa_printf(MSG_ERROR, "OWE: Invalid DH data received (len=%u)", owe_dh_len);
|
||||||
|
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the group ID from DH param (extension IE: group at offset 3) */
|
||||||
|
sta->owe_group = WPA_GET_LE16(owe_dh + 3);
|
||||||
|
if (sta->owe_group != OWE_DH_GRP19)
|
||||||
|
return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
if (owe_dh_len < OWE_DHIE_LEN - 2) {
|
||||||
|
wpa_printf(MSG_ERROR, "OWE: Invalid DH data received (len=%u)", owe_dh_len);
|
||||||
|
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sta->owe_ecdh) {
|
||||||
|
/* This is a workaround for mac80211 behavior of retransmitting
|
||||||
|
* the Association Request frames multiple times if the link
|
||||||
|
* layer retries (i.e., seq# remains same) fail. The mac80211
|
||||||
|
* initiated retransmission will use a different seq# and as
|
||||||
|
* such, will go through duplicate detection. If we were to
|
||||||
|
* change our DH key for that attempt, there would be two
|
||||||
|
* different DH shared secrets and the STA would likely select
|
||||||
|
* the wrong one. */
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"OWE: Try to reuse own previous DH key since the STA tried to go through OWE association again");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
sta->owe_ecdh = crypto_ecdh_init(OWE_DH_GRP19);
|
||||||
|
if (!sta->owe_ecdh) {
|
||||||
|
wpa_printf(MSG_ERROR, "OWE: Error initializing ECDH for STA");
|
||||||
|
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the DH shared secret
|
||||||
|
secret = crypto_ecdh_set_peerkey(sta->owe_ecdh, 0, owe_dh + 5, owe_dh_len - 3);
|
||||||
|
// secret = wpabuf_zeropad(secret, OWE_PRIME_LEN);
|
||||||
|
|
||||||
|
if (!secret) {
|
||||||
|
wpa_printf(MSG_ERROR, "OWE: Invalid peer DH public key");
|
||||||
|
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
}
|
||||||
|
wpa_hexdump_buf_key(MSG_DEBUG, "OWE: DH shared secret", secret);
|
||||||
|
|
||||||
|
/* prk = HKDF-extract(C | A | group, z) */
|
||||||
|
|
||||||
|
pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
|
||||||
|
pub = wpabuf_zeropad(pub, 32);
|
||||||
|
if (!pub) {
|
||||||
|
wpabuf_clear_free(secret);
|
||||||
|
wpa_printf(MSG_ERROR, "OWE: Failed to retrieve public key");
|
||||||
|
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PMKID = Truncate-128(Hash(C | A)) */
|
||||||
|
addr[0] = owe_dh + 5;
|
||||||
|
addr[1] = wpabuf_head(pub);
|
||||||
|
len[0] = owe_dh_len - 3;
|
||||||
|
len[1] = wpabuf_len(pub);
|
||||||
|
|
||||||
|
res = sha256_vector(2, addr, len, pmkid);
|
||||||
|
if (res < 0) {
|
||||||
|
wpabuf_free(pub);
|
||||||
|
wpabuf_clear_free(secret);
|
||||||
|
wpa_printf(MSG_ERROR, "OWE: PMKID calculation failed");
|
||||||
|
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hkey = wpabuf_alloc(owe_dh_len - 3 + wpabuf_len(pub) + 2);
|
||||||
|
if (!hkey) {
|
||||||
|
wpabuf_free(pub);
|
||||||
|
wpabuf_clear_free(secret);
|
||||||
|
wpa_printf(MSG_ERROR, "OWE: Memory allocation failed for hkey buffer");
|
||||||
|
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_DEBUG, "Peer public key", owe_dh+5, owe_dh_len-3);
|
||||||
|
wpabuf_put_data(hkey, owe_dh + 5, owe_dh_len - 3); /* C */
|
||||||
|
wpabuf_put_buf(hkey, pub); /* A */
|
||||||
|
wpabuf_free(pub);
|
||||||
|
wpabuf_put_le16(hkey, sta->owe_group); /* group */
|
||||||
|
|
||||||
|
res = hmac_sha256(wpabuf_head(hkey), wpabuf_len(hkey),
|
||||||
|
wpabuf_head(secret), wpabuf_len(secret), prk);
|
||||||
|
wpabuf_clear_free(hkey);
|
||||||
|
wpabuf_clear_free(secret);
|
||||||
|
|
||||||
|
if (res < 0) {
|
||||||
|
os_memset(prk, 0, SHA256_MAC_LEN);
|
||||||
|
wpa_printf(MSG_ERROR, "OWE: HMAC-SHA256 failed");
|
||||||
|
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
}
|
||||||
|
wpa_hexdump_key(MSG_DEBUG, "OWE: prk", prk, SHA256_MAC_LEN);
|
||||||
|
|
||||||
|
/* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
|
||||||
|
if (!sta->owe_pmk || sta->owe_pmk_len != SHA256_MAC_LEN) {
|
||||||
|
bin_clear_free(sta->owe_pmk,
|
||||||
|
sta->owe_pmk_len ? sta->owe_pmk_len : SHA256_MAC_LEN);
|
||||||
|
sta->owe_pmk = os_malloc(SHA256_MAC_LEN);
|
||||||
|
if (!sta->owe_pmk) {
|
||||||
|
os_memset(prk, 0, SHA256_MAC_LEN);
|
||||||
|
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
os_memset(sta->owe_pmk, 0, SHA256_MAC_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = hmac_sha256_kdf(prk, SHA256_MAC_LEN, NULL, (const u8 *)info,
|
||||||
|
os_strlen(info), sta->owe_pmk, SHA256_MAC_LEN);
|
||||||
|
os_memset(prk, 0, SHA256_MAC_LEN);
|
||||||
|
if (res < 0) {
|
||||||
|
bin_clear_free(sta->owe_pmk, SHA256_MAC_LEN);
|
||||||
|
sta->owe_pmk = NULL;
|
||||||
|
sta->owe_pmk_len = 0;
|
||||||
|
wpa_printf(MSG_ERROR, "OWE: HMAC-SHA256 KDF failed");
|
||||||
|
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump_key(MSG_DEBUG, "OWE: PMK", sta->owe_pmk, PMK_LEN);
|
||||||
|
wpa_hexdump(MSG_DEBUG, "OWE: PMKID", pmkid, PMKID_LEN);
|
||||||
|
|
||||||
|
sta->owe_pmk_len = SHA256_MAC_LEN;
|
||||||
|
|
||||||
|
// Add the PMK to the PMKSA cache
|
||||||
|
if (wpa_auth_pmksa_add2(hapd->wpa_auth, sta->addr, sta->owe_pmk, sta->owe_pmk_len,
|
||||||
|
pmkid, 0, WPA_KEY_MGMT_OWE, NULL) < 0) {
|
||||||
|
bin_clear_free(sta->owe_pmk, sta->owe_pmk_len);
|
||||||
|
sta->owe_pmk = NULL;
|
||||||
|
sta->owe_pmk_len = 0;
|
||||||
|
wpa_printf(MSG_ERROR, "OWE: Failed to add PMKSA cache entry");
|
||||||
|
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the PMKID in the STA's WPA state machine
|
||||||
|
os_memcpy(sta->wpa_sm->pmkid, pmkid, PMKID_LEN);
|
||||||
|
sta->wpa_sm->pmkid_set = 1;
|
||||||
|
|
||||||
|
return WLAN_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_OWE_SOFTAP */
|
||||||
|
|||||||
@@ -16,5 +16,9 @@ int handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
|
|||||||
u8 *buf, size_t len, u8 *bssid,
|
u8 *buf, size_t len, u8 *bssid,
|
||||||
u16 auth_transaction, u16 status);
|
u16 auth_transaction, u16 status);
|
||||||
u16 wpa_res_to_status_code(enum wpa_validate_result res);
|
u16 wpa_res_to_status_code(enum wpa_validate_result res);
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
uint16_t owe_process_assoc_req(struct hostapd_data *hapd, struct sta_info *sta, const u8 *owe_dh,
|
||||||
|
u8 owe_dh_len);
|
||||||
|
#endif /* CONFIG_OWE_SOFTAP */
|
||||||
|
|
||||||
#endif /* IEEE802_11_H */
|
#endif /* IEEE802_11_H */
|
||||||
|
|||||||
@@ -127,6 +127,10 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
|
|||||||
|
|
||||||
wpabuf_free(sta->wps_ie);
|
wpabuf_free(sta->wps_ie);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
bin_clear_free(sta->owe_pmk, PMK_LEN);
|
||||||
|
crypto_ecdh_deinit(sta->owe_ecdh);
|
||||||
|
#endif /* CONFIG_OWE_SOFTAP */
|
||||||
|
|
||||||
os_free(sta);
|
os_free(sta);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,12 @@ struct sta_info {
|
|||||||
struct wpabuf *sae_data;
|
struct wpabuf *sae_data;
|
||||||
#endif /* CONFIG_SAE */
|
#endif /* CONFIG_SAE */
|
||||||
#endif /* ESP_SUPPLICANT */
|
#endif /* ESP_SUPPLICANT */
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
u16 owe_group;
|
||||||
|
u8 *owe_pmk;
|
||||||
|
size_t owe_pmk_len;
|
||||||
|
struct crypto_ecdh *owe_ecdh;
|
||||||
|
#endif /* CONFIG_OWE_SOFTAP */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -136,8 +136,9 @@ static inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SAE
|
#if defined(CONFIG_SAE) || defined(CONFIG_OWE_SOFTAP)
|
||||||
struct sta_info *sta = ap_get_sta(hapd, addr);
|
struct sta_info *sta = ap_get_sta(hapd, addr);
|
||||||
|
#ifdef CONFIG_SAE
|
||||||
if (sta && sta->auth_alg == WLAN_AUTH_SAE) {
|
if (sta && sta->auth_alg == WLAN_AUTH_SAE) {
|
||||||
if (!sta->sae || prev_psk)
|
if (!sta->sae || prev_psk)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -150,6 +151,24 @@ static inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth,
|
|||||||
}
|
}
|
||||||
#endif /*CONFIG_SAE*/
|
#endif /*CONFIG_SAE*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
|
||||||
|
sta && sta->owe_pmk) {
|
||||||
|
return sta->owe_pmk;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) && sta) {
|
||||||
|
struct rsn_pmksa_cache_entry *sa;
|
||||||
|
|
||||||
|
sa = wpa_auth_sta_get_pmksa(sta->wpa_sm);
|
||||||
|
if (sa && sa->akmp == WPA_KEY_MGMT_OWE) {
|
||||||
|
return sa->pmk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_OWE_SOFTAP */
|
||||||
|
#endif /* defined(CONFIG_SAE) || defined(CONFIG_OWE_SOFTAP) */
|
||||||
|
|
||||||
return (u8*)hostapd_get_psk(hapd->conf, addr, prev_psk);
|
return (u8*)hostapd_get_psk(hapd->conf, addr, prev_psk);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1030,6 +1049,12 @@ void wpa_auth_add_sae_pmkid(struct wpa_state_machine *sm, const u8 *pmkid)
|
|||||||
sm->pmkid_set = 1;
|
sm->pmkid_set = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct rsn_pmksa_cache_entry *
|
||||||
|
wpa_auth_sta_get_pmksa(struct wpa_state_machine *sm)
|
||||||
|
{
|
||||||
|
return sm ? sm->pmksa : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int wpa_gmk_to_gtk(const u8 *gmk, const char *label, const u8 *addr,
|
static int wpa_gmk_to_gtk(const u8 *gmk, const char *label, const u8 *addr,
|
||||||
const u8 *gnonce, u8 *gtk, size_t gtk_len)
|
const u8 *gnonce, u8 *gtk, size_t gtk_len)
|
||||||
{
|
{
|
||||||
@@ -1465,7 +1490,8 @@ SM_STATE(WPA_PTK, INITIALIZE)
|
|||||||
wpa_remove_ptk(sm);
|
wpa_remove_ptk(sm);
|
||||||
wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 0);
|
wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 0);
|
||||||
sm->TimeoutCtr = 0;
|
sm->TimeoutCtr = 0;
|
||||||
if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
|
if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) ||
|
||||||
|
sm->wpa_key_mgmt == WPA_KEY_MGMT_OWE) {
|
||||||
wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
|
wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
|
||||||
WPA_EAPOL_authorized, 0);
|
WPA_EAPOL_authorized, 0);
|
||||||
}
|
}
|
||||||
@@ -1624,6 +1650,9 @@ SM_STATE(WPA_PTK, INITPSK)
|
|||||||
psk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, NULL);
|
psk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, NULL);
|
||||||
if (psk) {
|
if (psk) {
|
||||||
memcpy(sm->PMK, psk, PMK_LEN);
|
memcpy(sm->PMK, psk, PMK_LEN);
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
sm->pmk_len = PMK_LEN;
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_IEEE80211R_AP
|
#ifdef CONFIG_IEEE80211R_AP
|
||||||
memcpy(sm->xxkey, psk, PMK_LEN);
|
memcpy(sm->xxkey, psk, PMK_LEN);
|
||||||
sm->xxkey_len = PMK_LEN;
|
sm->xxkey_len = PMK_LEN;
|
||||||
@@ -1662,6 +1691,7 @@ SM_STATE(WPA_PTK, PTKSTART)
|
|||||||
*/
|
*/
|
||||||
if (sm->wpa == WPA_VERSION_WPA2 &&
|
if (sm->wpa == WPA_VERSION_WPA2 &&
|
||||||
(wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) ||
|
(wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) ||
|
||||||
|
(sm->wpa_key_mgmt == WPA_KEY_MGMT_OWE && sm->pmksa) ||
|
||||||
wpa_key_mgmt_sae(sm->wpa_key_mgmt))) {
|
wpa_key_mgmt_sae(sm->wpa_key_mgmt))) {
|
||||||
pmkid = buf;
|
pmkid = buf;
|
||||||
pmkid_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;
|
pmkid_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;
|
||||||
@@ -2246,7 +2276,8 @@ SM_STEP(WPA_PTK)
|
|||||||
wpa_auth_get_eapol(sm->wpa_auth, sm->addr,
|
wpa_auth_get_eapol(sm->wpa_auth, sm->addr,
|
||||||
WPA_EAPOL_keyRun) > 0)
|
WPA_EAPOL_keyRun) > 0)
|
||||||
SM_ENTER(WPA_PTK, INITPMK);
|
SM_ENTER(WPA_PTK, INITPMK);
|
||||||
else if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)
|
else if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) ||
|
||||||
|
(sm->wpa_key_mgmt == WPA_KEY_MGMT_OWE)
|
||||||
/* FIX: && 802.1X::keyRun */)
|
/* FIX: && 802.1X::keyRun */)
|
||||||
SM_ENTER(WPA_PTK, INITPSK);
|
SM_ENTER(WPA_PTK, INITPSK);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "common/defs.h"
|
#include "common/defs.h"
|
||||||
#include "common/eapol_common.h"
|
#include "common/eapol_common.h"
|
||||||
#include "common/wpa_common.h"
|
#include "common/wpa_common.h"
|
||||||
|
#include "ap/hostapd.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
@@ -327,5 +328,7 @@ static inline bool wpa_auth_pmf_enabled(struct wpa_auth_config *conf)
|
|||||||
return conf->ieee80211w != NO_MGMT_FRAME_PROTECTION;
|
return conf->ieee80211w != NO_MGMT_FRAME_PROTECTION;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
uint8_t *wpa_auth_write_assoc_resp_owe(struct hostapd_data *hapd, struct wpa_state_machine *sm,
|
||||||
|
u8 *pos, size_t max_len);
|
||||||
|
|
||||||
#endif /* WPA_AUTH_H */
|
#endif /* WPA_AUTH_H */
|
||||||
|
|||||||
@@ -234,6 +234,13 @@ static u8 * rsne_write_data(u8 *buf, size_t len, u8 *pos, int group,
|
|||||||
num_suites++;
|
num_suites++;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SAE */
|
#endif /* CONFIG_SAE */
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
if (key_mgmt & WPA_KEY_MGMT_OWE) {
|
||||||
|
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_OWE);
|
||||||
|
pos += RSN_SELECTOR_LEN;
|
||||||
|
num_suites++;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_OWE_SOFTAP */
|
||||||
|
|
||||||
#ifdef CONFIG_RSN_TESTING
|
#ifdef CONFIG_RSN_TESTING
|
||||||
if (rsn_testing) {
|
if (rsn_testing) {
|
||||||
@@ -611,6 +618,10 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
|
|||||||
selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
|
selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
|
||||||
else if (data.key_mgmt & WPA_KEY_MGMT_PSK)
|
else if (data.key_mgmt & WPA_KEY_MGMT_PSK)
|
||||||
selector = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
|
selector = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
else if (data.key_mgmt & WPA_KEY_MGMT_OWE)
|
||||||
|
selector = RSN_AUTH_KEY_MGMT_OWE;
|
||||||
|
#endif /* CONFIG_OWE_SOFTAP */
|
||||||
|
|
||||||
selector = wpa_cipher_to_suite(WPA_PROTO_RSN,
|
selector = wpa_cipher_to_suite(WPA_PROTO_RSN,
|
||||||
data.pairwise_cipher);
|
data.pairwise_cipher);
|
||||||
@@ -692,6 +703,10 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
|
|||||||
#endif /* CONFIG_SAE */
|
#endif /* CONFIG_SAE */
|
||||||
else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)
|
else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)
|
||||||
sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X;
|
sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X;
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
else if (key_mgmt & WPA_KEY_MGMT_OWE)
|
||||||
|
sm->wpa_key_mgmt = WPA_KEY_MGMT_OWE;
|
||||||
|
#endif /* CONFIG_OWE_SOFTAP */
|
||||||
else
|
else
|
||||||
sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
|
sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
|
||||||
|
|
||||||
@@ -810,6 +825,12 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
|
|||||||
os_memcpy(wpa_auth->dot11RSNAPMKIDUsed, pmkid, PMKID_LEN);
|
os_memcpy(wpa_auth->dot11RSNAPMKIDUsed, pmkid, PMKID_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
if (sm->wpa_key_mgmt == WPA_KEY_MGMT_OWE && !sm->pmksa) {
|
||||||
|
wpa_printf(MSG_DEBUG, "No PMKSA cache entry found for OWE");
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_OWE_SOFTAP */
|
||||||
|
|
||||||
#ifdef CONFIG_SAE
|
#ifdef CONFIG_SAE
|
||||||
if ((sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE || sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE_EXT_KEY) && data.num_pmkid &&
|
if ((sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE || sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE_EXT_KEY) && data.num_pmkid &&
|
||||||
!sm->pmksa) {
|
!sm->pmksa) {
|
||||||
@@ -847,3 +868,18 @@ int wpa_auth_uses_mfp(struct wpa_state_machine *sm)
|
|||||||
{
|
{
|
||||||
return sm ? sm->mgmt_frame_prot : 0;
|
return sm ? sm->mgmt_frame_prot : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OWE_SOFTAP
|
||||||
|
uint8_t *wpa_auth_write_assoc_resp_owe(struct hostapd_data *hapd, struct wpa_state_machine *sm,
|
||||||
|
u8 *pos, size_t max_len)
|
||||||
|
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = wpa_write_rsn_ie(&hapd->wpa_auth->conf, pos, max_len,
|
||||||
|
sm->pmksa ? sm->pmksa->pmkid : NULL);
|
||||||
|
if (res < 0)
|
||||||
|
return pos;
|
||||||
|
return pos + res;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_OWE_SOFTAP */
|
||||||
|
|||||||
@@ -358,10 +358,10 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s)
|
|||||||
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192)
|
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192)
|
||||||
return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
|
return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_OWE_STA
|
#if defined(CONFIG_OWE_STA) || defined(CONFIG_OWE_SOFTAP)
|
||||||
if(RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OWE)
|
if(RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OWE)
|
||||||
return WPA_KEY_MGMT_OWE;
|
return WPA_KEY_MGMT_OWE;
|
||||||
#endif /* CONFIG_OWE_STA */
|
#endif /* CONFIG_OWE_STA || CONFIG_OWE_SOFTAP */
|
||||||
#ifdef CONFIG_DPP
|
#ifdef CONFIG_DPP
|
||||||
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_DPP)
|
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_DPP)
|
||||||
return WPA_KEY_MGMT_DPP;
|
return WPA_KEY_MGMT_DPP;
|
||||||
@@ -987,7 +987,7 @@ int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
|
|||||||
os_memcpy(mic, hash, 24);
|
os_memcpy(mic, hash, 24);
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_SUITEB192 */
|
#endif /* CONFIG_SUITEB192 */
|
||||||
#ifdef CONFIG_OWE_STA
|
#if defined(CONFIG_OWE_STA) || defined(CONFIG_OWE_SOFTAP)
|
||||||
case WPA_KEY_MGMT_OWE:
|
case WPA_KEY_MGMT_OWE:
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"WPA: EAPOL-Key MIC using HMAC-SHA%u (AKM-defined - OWE)",
|
"WPA: EAPOL-Key MIC using HMAC-SHA%u (AKM-defined - OWE)",
|
||||||
@@ -1003,7 +1003,7 @@ int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
|
|||||||
os_memcpy(mic, hash, key_len);
|
os_memcpy(mic, hash, key_len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#endif /* CONFIG_OWE_STA */
|
#endif /* CONFIG_OWE_STA || CONFIG_OWE_SOFTAP */
|
||||||
#ifdef CONFIG_DPP
|
#ifdef CONFIG_DPP
|
||||||
case WPA_KEY_MGMT_DPP:
|
case WPA_KEY_MGMT_DPP:
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
|
|||||||
@@ -157,10 +157,17 @@ Enhanced Open™ is used for providing security and privacy to users connecting
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
{IDF_TARGET_NAME} supports Wi-Fi Enhanced Open™ only in station mode.
|
{IDF_TARGET_NAME} supports Wi-Fi Enhanced Open™ in station mode for both OWE Transition Mode and OWE-only networks. In SoftAP mode, only **OWE-only** operation is supported; **OWE Transition Mode is not supported**.
|
||||||
|
|
||||||
|
|
||||||
Setting up OWE with {IDF_TARGET_NAME}
|
Setting up OWE with {IDF_TARGET_NAME}
|
||||||
++++++++++++++++++++++++++++++++++++++
|
++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
For station mode :
|
||||||
|
|
||||||
A configuration option :ref:`CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA` and configuration parameter :cpp:type:`owe_enabled` in :cpp:type:`wifi_sta_config_t` is provided to enable OWE support for the station. To use OWE transition mode, along with the configuration provided above, `authmode` from :cpp:type:`wifi_scan_threshold_t` should be set to ``WIFI_AUTH_OPEN``.
|
A configuration option :ref:`CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA` and configuration parameter :cpp:type:`owe_enabled` in :cpp:type:`wifi_sta_config_t` is provided to enable OWE support for the station. To use OWE transition mode, along with the configuration provided above, `authmode` from :cpp:type:`wifi_scan_threshold_t` should be set to ``WIFI_AUTH_OPEN``.
|
||||||
|
|
||||||
|
|
||||||
|
For softap mode :
|
||||||
|
|
||||||
|
A configuration option :ref:`CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_SOFTAP` from menuconfig should be enabled and configuration parameter `authmode` from :cpp:type:`wifi_ap_config_t` should be set to ``WIFI_AUTH_OWE``. SoftAP does not support OWE Transition Mode; configure ``WIFI_AUTH_OWE`` only.
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ void wifi_init_softap(void)
|
|||||||
.gtk_rekey_interval = EXAMPLE_GTK_REKEY_INTERVAL,
|
.gtk_rekey_interval = EXAMPLE_GTK_REKEY_INTERVAL,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {
|
if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0 && wifi_config.ap.authmode != WIFI_AUTH_OWE) {
|
||||||
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
|
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user