mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +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
|
||||
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
|
||||
bool "WiFi SLP IRAM speed optimization"
|
||||
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
|
||||
#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_CACHE_TX_BUF_BIT (1<<1)
|
||||
#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_BSS_MAX_IDLE_BIT (1<<8)
|
||||
#define CONFIG_FEATURE_WIFI_PASSIVE_HIDDEN_AP_BIT (1<<9)
|
||||
#define CONFIG_FEATURE_OWE_SOFTAP_BIT (1<<10)
|
||||
|
||||
/* Set additional WiFi features and capabilities */
|
||||
#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_ENTERPRISE | \
|
||||
WIFI_ENABLE_BSS_MAX_IDLE | \
|
||||
WIFI_ENABLE_PASSIVE_HIDDEN_AP)
|
||||
WIFI_ENABLE_PASSIVE_HIDDEN_AP | \
|
||||
WIFI_ENABLE_OWE_SOFTAP)
|
||||
|
||||
#define WIFI_INIT_CONFIG_DEFAULT() { \
|
||||
.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
|
||||
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
|
||||
bool "WiFi SLP IRAM speed optimization"
|
||||
select PM_SLP_DEFAULT_PARAMS_OPT
|
||||
|
||||
@@ -142,6 +142,13 @@ if WIFI_RMT_WPA3_COMPATIBLE_SUPPORT
|
||||
default WIFI_RMT_WPA3_COMPATIBLE_SUPPORT
|
||||
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
|
||||
config ESP_WIFI_SLP_IRAM_OPT # ignore: multiple-definition
|
||||
bool
|
||||
|
||||
@@ -290,6 +290,12 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs;
|
||||
#define WIFI_ENABLE_PASSIVE_HIDDEN_AP 0
|
||||
#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_CACHE_TX_BUF_BIT (1<<1)
|
||||
#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_BSS_MAX_IDLE_BIT (1<<8)
|
||||
#define CONFIG_FEATURE_WIFI_PASSIVE_HIDDEN_AP_BIT (1<<9)
|
||||
#define CONFIG_FEATURE_OWE_SOFTAP_BIT (1<<10)
|
||||
|
||||
/* Set additional WiFi features and capabilities */
|
||||
#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_ENTERPRISE | \
|
||||
WIFI_ENABLE_BSS_MAX_IDLE | \
|
||||
WIFI_ENABLE_PASSIVE_HIDDEN_AP)
|
||||
WIFI_ENABLE_PASSIVE_HIDDEN_AP | \
|
||||
WIFI_ENABLE_OWE_SOFTAP)
|
||||
|
||||
#define WIFI_INIT_CONFIG_DEFAULT() { \
|
||||
.osi_funcs = &g_wifi_osi_funcs, \
|
||||
|
||||
@@ -362,4 +362,7 @@ endif()
|
||||
if(CONFIG_ESP_WIFI_NAN_USD_ENABLE)
|
||||
target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_NAN_USD)
|
||||
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)
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -28,6 +28,12 @@
|
||||
#include "ap/ieee802_11.h"
|
||||
#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;
|
||||
|
||||
#ifdef CONFIG_SAE
|
||||
@@ -48,7 +54,8 @@ static bool authmode_has_rsn(uint8_t authmode)
|
||||
return (authmode == WIFI_AUTH_WPA2_PSK ||
|
||||
authmode == WIFI_AUTH_WPA_WPA2_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)
|
||||
@@ -192,6 +199,13 @@ void *hostap_init(void)
|
||||
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
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);
|
||||
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);
|
||||
@@ -365,14 +379,35 @@ u16 esp_send_assoc_resp(struct hostapd_data *hapd, const u8 *addr,
|
||||
u8 buf[ASSOC_RESP_LENGTH];
|
||||
wifi_mgmt_frm_req_t *reply = NULL;
|
||||
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;
|
||||
|
||||
if (!omit_rsnxe) {
|
||||
if (!omit_rsnxe && !owe_resp) {
|
||||
send_len = esp_wifi_build_rsnxe(hapd, buf, ASSOC_RESP_LENGTH);
|
||||
}
|
||||
|
||||
esp_wifi_set_appie_internal(WIFI_APPIE_ASSOC_RESP, buf, send_len, 0);
|
||||
if (!owe_resp) {
|
||||
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));
|
||||
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,
|
||||
u8 wpa_ie_len, u8 *rsnxe, uint16_t rsnxe_len,
|
||||
bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason, uint8_t *rsn_selection_ie)
|
||||
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)
|
||||
{
|
||||
struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal();
|
||||
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;
|
||||
#endif
|
||||
|
||||
if (!sta || !bssid || !wpa_ie) {
|
||||
if (!sta || !bssid || !assoc_req || !assoc_req->wpa_ie) {
|
||||
return false;
|
||||
}
|
||||
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
|
||||
#define RSN_SELECTION_IE_OUI_LEN 4
|
||||
if (rsn_selection_ie) {
|
||||
rsn_selection_variant_len = rsn_selection_ie[1] - RSN_SELECTION_IE_OUI_LEN;
|
||||
rsn_selection_variant_ie = &rsn_selection_ie[RSN_SELECTION_IE_OUI_LEN + 2];
|
||||
if (assoc_req->rsn_selection_ie) {
|
||||
rsn_selection_variant_len = assoc_req->rsn_selection_ie[1] - RSN_SELECTION_IE_OUI_LEN;
|
||||
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);
|
||||
#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
|
||||
if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae &&
|
||||
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);
|
||||
|
||||
#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:
|
||||
if (!rsnxe) {
|
||||
if (!assoc_req->rsnxe) {
|
||||
omit_rsnxe = true;
|
||||
}
|
||||
|
||||
@@ -479,7 +537,7 @@ send_resp:
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
#ifdef CONFIG_OWE_STA
|
||||
|
||||
#include "crypto/crypto.h"
|
||||
#include "esp_owe_i.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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
#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
|
||||
*/
|
||||
@@ -20,4 +20,26 @@ void owe_deinit(void);
|
||||
void esp_wifi_register_owe_cb(struct wpa_funcs *wpa_cb);
|
||||
|
||||
#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 */
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -120,6 +120,21 @@ typedef struct {
|
||||
uint8_t rsnxe_capa;
|
||||
} 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 {
|
||||
bool (*wpa_sta_init)(void);
|
||||
bool (*wpa_sta_deinit)(void);
|
||||
@@ -130,7 +145,7 @@ struct wpa_funcs {
|
||||
bool (*wpa_sta_in_4way_handshake)(void);
|
||||
void *(*wpa_ap_init)(void);
|
||||
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);
|
||||
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);
|
||||
@@ -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);
|
||||
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);
|
||||
uint8_t esp_wifi_ap_get_owe_config_internal(void);
|
||||
|
||||
#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
|
||||
|
||||
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 hostapd_data *hapd = hostapd_get_hapd_data();
|
||||
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) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -451,7 +468,19 @@ process_old_sta:
|
||||
goto fail;
|
||||
}
|
||||
#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;
|
||||
} else {
|
||||
goto fail;
|
||||
|
||||
@@ -395,9 +395,21 @@ const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
|
||||
const u8 *addr, const u8 *prev_psk);
|
||||
int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf);
|
||||
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,
|
||||
bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason, uint8_t *rsn_selection_ie);
|
||||
|
||||
struct hostap_assoc_sta_req {
|
||||
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);
|
||||
|
||||
#endif /* HOSTAPD_CONFIG_H */
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "common/sae.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
@@ -20,6 +21,13 @@
|
||||
#include "esp_wpa3_i.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
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#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,
|
||||
u16 auth_transaction, u16 status);
|
||||
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 */
|
||||
|
||||
@@ -127,6 +127,10 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
|
||||
wpabuf_free(sta->wps_ie);
|
||||
#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);
|
||||
}
|
||||
|
||||
@@ -69,6 +69,12 @@ struct sta_info {
|
||||
struct wpabuf *sae_data;
|
||||
#endif /* CONFIG_SAE */
|
||||
#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;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SAE
|
||||
#if defined(CONFIG_SAE) || defined(CONFIG_OWE_SOFTAP)
|
||||
struct sta_info *sta = ap_get_sta(hapd, addr);
|
||||
#ifdef CONFIG_SAE
|
||||
if (sta && sta->auth_alg == WLAN_AUTH_SAE) {
|
||||
if (!sta->sae || prev_psk)
|
||||
return NULL;
|
||||
@@ -150,6 +151,24 @@ static inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth,
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
||||
@@ -1030,6 +1049,12 @@ void wpa_auth_add_sae_pmkid(struct wpa_state_machine *sm, const u8 *pmkid)
|
||||
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,
|
||||
const u8 *gnonce, u8 *gtk, size_t gtk_len)
|
||||
{
|
||||
@@ -1465,7 +1490,8 @@ SM_STATE(WPA_PTK, INITIALIZE)
|
||||
wpa_remove_ptk(sm);
|
||||
wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 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_EAPOL_authorized, 0);
|
||||
}
|
||||
@@ -1624,6 +1650,9 @@ SM_STATE(WPA_PTK, INITPSK)
|
||||
psk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, NULL);
|
||||
if (psk) {
|
||||
memcpy(sm->PMK, psk, PMK_LEN);
|
||||
#ifdef CONFIG_OWE_SOFTAP
|
||||
sm->pmk_len = PMK_LEN;
|
||||
#endif
|
||||
#ifdef CONFIG_IEEE80211R_AP
|
||||
memcpy(sm->xxkey, psk, PMK_LEN);
|
||||
sm->xxkey_len = PMK_LEN;
|
||||
@@ -1662,6 +1691,7 @@ SM_STATE(WPA_PTK, PTKSTART)
|
||||
*/
|
||||
if (sm->wpa == WPA_VERSION_WPA2 &&
|
||||
(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))) {
|
||||
pmkid = buf;
|
||||
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_EAPOL_keyRun) > 0)
|
||||
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 */)
|
||||
SM_ENTER(WPA_PTK, INITPSK);
|
||||
break;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "common/defs.h"
|
||||
#include "common/eapol_common.h"
|
||||
#include "common/wpa_common.h"
|
||||
#include "ap/hostapd.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#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;
|
||||
#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 */
|
||||
|
||||
@@ -234,6 +234,13 @@ static u8 * rsne_write_data(u8 *buf, size_t len, u8 *pos, int group,
|
||||
num_suites++;
|
||||
}
|
||||
#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
|
||||
if (rsn_testing) {
|
||||
@@ -611,6 +618,10 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
|
||||
selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
|
||||
else if (data.key_mgmt & WPA_KEY_MGMT_PSK)
|
||||
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,
|
||||
data.pairwise_cipher);
|
||||
@@ -692,6 +703,10 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
|
||||
#endif /* CONFIG_SAE */
|
||||
else if (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
|
||||
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);
|
||||
}
|
||||
|
||||
#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
|
||||
if ((sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE || sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE_EXT_KEY) && data.num_pmkid &&
|
||||
!sm->pmksa) {
|
||||
@@ -847,3 +868,18 @@ int wpa_auth_uses_mfp(struct wpa_state_machine *sm)
|
||||
{
|
||||
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)
|
||||
return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
|
||||
#endif
|
||||
#ifdef CONFIG_OWE_STA
|
||||
#if defined(CONFIG_OWE_STA) || defined(CONFIG_OWE_SOFTAP)
|
||||
if(RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OWE)
|
||||
return WPA_KEY_MGMT_OWE;
|
||||
#endif /* CONFIG_OWE_STA */
|
||||
#endif /* CONFIG_OWE_STA || CONFIG_OWE_SOFTAP */
|
||||
#ifdef CONFIG_DPP
|
||||
if (RSN_SELECTOR_GET(s) == RSN_AUTH_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);
|
||||
break;
|
||||
#endif /* CONFIG_SUITEB192 */
|
||||
#ifdef CONFIG_OWE_STA
|
||||
#if defined(CONFIG_OWE_STA) || defined(CONFIG_OWE_SOFTAP)
|
||||
case WPA_KEY_MGMT_OWE:
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"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);
|
||||
break;
|
||||
|
||||
#endif /* CONFIG_OWE_STA */
|
||||
#endif /* CONFIG_OWE_STA || CONFIG_OWE_SOFTAP */
|
||||
#ifdef CONFIG_DPP
|
||||
case WPA_KEY_MGMT_DPP:
|
||||
wpa_printf(MSG_DEBUG,
|
||||
|
||||
Reference in New Issue
Block a user