mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/sae_sta_h2e' into 'master'
SAE H2E support for STA See merge request espressif/esp-idf!17860
This commit is contained in:
commit
5f9bbf71fe
@ -2106,7 +2106,6 @@ sta_recv_mgmt = 0x40002094;
|
||||
ieee80211_send_setup = 0x40002098;
|
||||
ieee80211_send_probereq = 0x4000209c;
|
||||
sta_auth_shared = 0x400020a4;
|
||||
sta_auth_sae = 0x400020a8;
|
||||
cnx_coexist_timeout_process = 0x400020ac;
|
||||
ieee80211_alloc_challenge = 0x400020b0;
|
||||
cnx_assoc_timeout = 0x400020b4;
|
||||
|
@ -254,7 +254,8 @@ typedef struct {
|
||||
uint32_t mbo_enabled:1; /**< Whether MBO is enabled for the connection */
|
||||
uint32_t ft_enabled:1; /**< Whether FT is enabled for the connection */
|
||||
uint32_t owe_enabled:1; /**< Whether OWE is enabled for the connection */
|
||||
uint32_t reserved:27; /**< Reserved for future feature set */
|
||||
uint32_t sae_pwe_h2e:2; /**< Whether SAE hash to element is enabled */
|
||||
uint32_t reserved:25; /**< Reserved for future feature set */
|
||||
} wifi_sta_config_t;
|
||||
|
||||
/** @brief Configuration data for ESP32 AP or STA.
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 81ab3ab615a7b7741a466958b90f38cdb9413ad2
|
||||
Subproject commit ec0327abd2d420062224d3a741f3cfd394bd8aae
|
@ -46,6 +46,21 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
struct crypto_bignum * crypto_bignum_init_uint(unsigned int val)
|
||||
{
|
||||
|
||||
mbedtls_mpi *bn = os_zalloc(sizeof(mbedtls_mpi));
|
||||
if (bn == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mbedtls_mpi_init(bn);
|
||||
mbedtls_mpi_lset(bn, val);
|
||||
|
||||
return (struct crypto_bignum *)bn;
|
||||
}
|
||||
|
||||
|
||||
void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
|
||||
{
|
||||
mbedtls_mpi_free((mbedtls_mpi *)n);
|
||||
@ -163,6 +178,39 @@ int crypto_bignum_mulmod(const struct crypto_bignum *a,
|
||||
}
|
||||
|
||||
|
||||
int crypto_bignum_sqrmod(const struct crypto_bignum *a,
|
||||
const struct crypto_bignum *b,
|
||||
struct crypto_bignum *c)
|
||||
{
|
||||
int res;
|
||||
struct crypto_bignum *tmp = crypto_bignum_init();
|
||||
if (!tmp) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = mbedtls_mpi_copy((mbedtls_mpi *) tmp,(const mbedtls_mpi *) a);
|
||||
res = crypto_bignum_mulmod(a,tmp,b,c);
|
||||
|
||||
crypto_bignum_deinit(tmp, 0);
|
||||
return res ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
|
||||
struct crypto_bignum *r)
|
||||
{
|
||||
int res;
|
||||
res = mbedtls_mpi_copy((mbedtls_mpi *) r,(const mbedtls_mpi *) a);
|
||||
if (res) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = mbedtls_mpi_shift_r((mbedtls_mpi *)r, n);
|
||||
return res ? -1 : 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int crypto_bignum_cmp(const struct crypto_bignum *a,
|
||||
const struct crypto_bignum *b)
|
||||
{
|
||||
|
@ -115,6 +115,11 @@ size_t crypto_ec_prime_len(struct crypto_ec *e)
|
||||
return mbedtls_mpi_size(&e->group.P);
|
||||
}
|
||||
|
||||
size_t crypto_ec_order_len(struct crypto_ec *e)
|
||||
{
|
||||
return mbedtls_mpi_size(&e->group.N);
|
||||
}
|
||||
|
||||
|
||||
size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
|
||||
{
|
||||
@ -152,6 +157,12 @@ const struct crypto_bignum *crypto_ec_get_order(struct crypto_ec *e)
|
||||
}
|
||||
|
||||
|
||||
const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
|
||||
{
|
||||
return (const struct crypto_bignum *) &e->group.B;
|
||||
}
|
||||
|
||||
|
||||
void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
|
||||
{
|
||||
mbedtls_ecp_point_free((mbedtls_ecp_point *) p);
|
||||
|
@ -57,7 +57,7 @@ static int handle_action_frm(u8 *frame, size_t len,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_SUPPLICANT_TASK */
|
||||
|
||||
#if defined(CONFIG_WPA_11KV_SUPPORT)
|
||||
static void handle_rrm_frame(struct wpa_supplicant *wpa_s, u8 *sender,
|
||||
@ -99,7 +99,7 @@ static int mgmt_rx_action(u8 *frame, size_t len, u8 *sender, u32 rssi, u8 channe
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(CONFIG_WPA_11KV_SUPPORT) */
|
||||
|
||||
#ifdef CONFIG_SUPPLICANT_TASK
|
||||
static void btm_rrm_task(void *pvParameters)
|
||||
@ -153,7 +153,7 @@ static void btm_rrm_task(void *pvParameters)
|
||||
/* At this point, we completed */
|
||||
os_task_delete(NULL);
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_SUPPLICANT_TASK */
|
||||
|
||||
static void clear_bssid_flag(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
@ -192,7 +192,7 @@ static void register_mgmt_frames(struct wpa_supplicant *wpa_s)
|
||||
|
||||
if (wpa_s->subtype)
|
||||
wpa_s->type |= 1 << WLAN_FC_STYPE_ACTION;
|
||||
#endif
|
||||
#endif /* CONFIG_WPA_11KV_SUPPORT */
|
||||
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
/* register auth/assoc frames if FT is enabled */
|
||||
@ -200,7 +200,7 @@ static void register_mgmt_frames(struct wpa_supplicant *wpa_s)
|
||||
wpa_s->type |= (1 << WLAN_FC_STYPE_AUTH) |
|
||||
(1 << WLAN_FC_STYPE_ASSOC_RESP) |
|
||||
(1 << WLAN_FC_STYPE_REASSOC_RESP);
|
||||
#endif
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype);
|
||||
}
|
||||
|
||||
@ -240,7 +240,7 @@ static void supplicant_sta_disconn_handler(void* arg, esp_event_base_t event_bas
|
||||
#ifdef CONFIG_WPA_11KV_SUPPORT
|
||||
wpas_rrm_reset(wpa_s);
|
||||
wpas_clear_beacon_rep_data(wpa_s);
|
||||
#endif
|
||||
#endif /* CONFIG_WPA_11KV_SUPPORT */
|
||||
if (wpa_s->current_bss) {
|
||||
wpa_s->current_bss = NULL;
|
||||
}
|
||||
@ -280,7 +280,7 @@ static int handle_assoc_frame(u8 *frame, size_t len,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
|
||||
static int ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender,
|
||||
u32 rssi, u8 channel, u64 current_tsf)
|
||||
@ -300,16 +300,16 @@ static int ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender,
|
||||
case WLAN_FC_STYPE_REASSOC_RESP:
|
||||
ret = handle_assoc_frame(frame, len, sender, rssi, channel);
|
||||
break;
|
||||
#endif
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
#if defined(CONFIG_WPA_11KV_SUPPORT)
|
||||
case WLAN_FC_STYPE_ACTION:
|
||||
#ifdef CONFIG_SUPPLICANT_TASK
|
||||
ret = handle_action_frm(frame, len, sender, rssi, channel);
|
||||
#else
|
||||
#else /* CONFIG_SUPPLICANT_TASK */
|
||||
ret = mgmt_rx_action(frame, len, sender, rssi, channel);
|
||||
#endif
|
||||
#endif /* CONFIG_SUPPLICANT_TASK */
|
||||
break;
|
||||
#endif
|
||||
#endif /* defined(CONFIG_WPA_11KV_SUPPORT) */
|
||||
default:
|
||||
ret = -1;
|
||||
break;
|
||||
@ -341,7 +341,7 @@ bool mbo_bss_profile_match(u8 *bssid)
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_MBO */
|
||||
|
||||
int esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
|
||||
{
|
||||
@ -369,11 +369,11 @@ int esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
|
||||
ret = -1;
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_SUPPLICANT_TASK */
|
||||
#ifdef CONFIG_WPA_11KV_SUPPORT
|
||||
wpas_rrm_reset(wpa_s);
|
||||
wpas_clear_beacon_rep_data(wpa_s);
|
||||
#endif
|
||||
#endif /* CONFIG_WPA_11KV_SUPPORT */
|
||||
esp_scan_init(wpa_s);
|
||||
|
||||
esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED,
|
||||
@ -385,7 +385,7 @@ int esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
|
||||
wpa_s->subtype = 0;
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
wpa_s->type |= (1 << WLAN_FC_STYPE_ASSOC_RESP) | (1 << WLAN_FC_STYPE_REASSOC_RESP) | (1 << WLAN_FC_STYPE_AUTH);
|
||||
#endif
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
if (esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype) != ESP_OK) {
|
||||
ret = -1;
|
||||
goto err;
|
||||
@ -393,7 +393,7 @@ int esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
|
||||
wpa_cb->wpa_sta_rx_mgmt = ieee80211_handle_rx_frm;
|
||||
#ifdef CONFIG_MBO
|
||||
dl_list_init(&wpa_s->bss_tmp_disallowed);
|
||||
#endif
|
||||
#endif /* CONFIG_MBO */
|
||||
return 0;
|
||||
err:
|
||||
esp_supplicant_common_deinit();
|
||||
@ -408,7 +408,7 @@ void esp_supplicant_common_deinit(void)
|
||||
#ifdef CONFIG_WPA_11KV_SUPPORT
|
||||
wpas_rrm_reset(wpa_s);
|
||||
wpas_clear_beacon_rep_data(wpa_s);
|
||||
#endif
|
||||
#endif /* CONFIG_WPA_11KV_SUPPORT */
|
||||
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED,
|
||||
&supplicant_sta_conn_handler);
|
||||
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED,
|
||||
@ -428,7 +428,7 @@ void esp_supplicant_common_deinit(void)
|
||||
s_supplicant_api_lock = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_SUPPLICANT_TASK */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_WPA_11KV_SUPPORT
|
||||
@ -555,7 +555,7 @@ static size_t get_rm_enabled_ie(uint8_t *ie, size_t len)
|
||||
*pos |= WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
|
||||
#ifdef SCAN_CACHE_SUPPORTED
|
||||
WLAN_RRM_CAPS_BEACON_REPORT_TABLE |
|
||||
#endif
|
||||
#endif /* SCAN_CACHE_SUPPORTED */
|
||||
WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE;
|
||||
|
||||
os_memcpy(ie, rrm_ie, sizeof(rrm_ie));
|
||||
@ -618,7 +618,7 @@ static uint8_t get_operating_class_ie(uint8_t *ie, size_t len)
|
||||
|
||||
return op_class_ie_len + 2;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_MBO */
|
||||
|
||||
static uint8_t get_extended_caps_ie(uint8_t *ie, size_t len)
|
||||
{
|
||||
@ -642,7 +642,7 @@ static uint8_t get_extended_caps_ie(uint8_t *ie, size_t len)
|
||||
return ext_caps_ie_len + 2;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* CONFIG_WPA_11KV_SUPPORT */
|
||||
|
||||
void esp_set_scan_ie(void)
|
||||
{
|
||||
@ -664,12 +664,12 @@ void esp_set_scan_ie(void)
|
||||
ie_len = get_mbo_oce_scan_ie(pos, len);
|
||||
pos += ie_len;
|
||||
len -= ie_len;
|
||||
#endif
|
||||
#endif /* CONFIG_MBO */
|
||||
esp_wifi_unset_appie_internal(WIFI_APPIE_PROBEREQ);
|
||||
esp_wifi_set_appie_internal(WIFI_APPIE_PROBEREQ, ie, SCAN_IE_LEN - len, 0);
|
||||
os_free(ie);
|
||||
#undef SCAN_IE_LEN
|
||||
#endif
|
||||
#endif /* CONFIG_WPA_11KV_SUPPORT */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
@ -703,52 +703,8 @@ static size_t add_mdie(uint8_t *bssid, uint8_t *ie, size_t len)
|
||||
|
||||
return mdie_len;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
|
||||
void esp_set_assoc_ie(uint8_t *bssid, const u8 *ies, size_t ies_len, bool mdie)
|
||||
{
|
||||
#define ASSOC_IE_LEN 128
|
||||
uint8_t *ie, *pos;
|
||||
size_t len = ASSOC_IE_LEN, ie_len;
|
||||
|
||||
ie = os_malloc(ASSOC_IE_LEN + ies_len);
|
||||
if (!ie) {
|
||||
wpa_printf(MSG_ERROR, "failed to allocate ie");
|
||||
return;
|
||||
}
|
||||
pos = ie;
|
||||
#ifdef CONFIG_WPA_11KV_SUPPORT
|
||||
ie_len = get_extended_caps_ie(pos, len);
|
||||
pos += ie_len;
|
||||
len -= ie_len;
|
||||
ie_len = get_rm_enabled_ie(pos, len);
|
||||
pos += ie_len;
|
||||
len -= ie_len;
|
||||
#ifdef CONFIG_MBO
|
||||
ie_len = get_operating_class_ie(pos, len);
|
||||
pos += ie_len;
|
||||
len -= ie_len;
|
||||
ie_len = get_mbo_oce_assoc_ie(pos, len);
|
||||
pos += ie_len;
|
||||
len -= ie_len;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
if (mdie) {
|
||||
ie_len = add_mdie(bssid, pos, len);
|
||||
pos += ie_len;
|
||||
len -= ie_len;
|
||||
}
|
||||
#endif
|
||||
if (ies_len) {
|
||||
os_memcpy(pos, ies, ies_len);
|
||||
pos += ies_len;
|
||||
len -= ies_len;
|
||||
}
|
||||
esp_wifi_set_appie_internal(WIFI_APPIE_ASSOC_REQ, ie, ASSOC_IE_LEN - len, 0);
|
||||
os_free(ie);
|
||||
#undef ASSOC_IE_LEN
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
int wpa_sm_update_ft_ies(struct wpa_sm *sm, const u8 *md,
|
||||
@ -768,7 +724,7 @@ int wpa_sm_update_ft_ies(struct wpa_sm *sm, const u8 *md,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
|
||||
void esp_get_tx_power(uint8_t *tx_power)
|
||||
{
|
||||
@ -846,8 +802,8 @@ int esp_supplicant_post_evt(uint32_t evt_id, uint32_t data)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#endif /* CONFIG_SUPPLICANT_TASK */
|
||||
#else /* defined(CONFIG_WPA_11KV_SUPPORT) || defined(CONFIG_IEEE80211R) */
|
||||
int esp_rrm_send_neighbor_rep_request(neighbor_rep_request_cb cb,
|
||||
void *cb_ctx)
|
||||
{
|
||||
@ -866,11 +822,61 @@ int esp_mbo_update_non_pref_chan(struct non_pref_chan_s *non_pref_chan)
|
||||
return -1;
|
||||
}
|
||||
void esp_set_scan_ie(void) { }
|
||||
void esp_set_assoc_ie(uint8_t *bssid, const u8 *ies, size_t ies_len, bool mdie) { }
|
||||
int esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
|
||||
{
|
||||
wpa_cb->wpa_sta_rx_mgmt = NULL;
|
||||
return 0;
|
||||
}
|
||||
void esp_supplicant_common_deinit(void) { }
|
||||
#endif
|
||||
#endif /* defined(CONFIG_WPA_11KV_SUPPORT) || defined(CONFIG_IEEE80211R) */
|
||||
|
||||
#if defined(CONFIG_WPA_11KV_SUPPORT) || defined(CONFIG_IEEE80211R) || defined(CONFIG_WPA3_SAE)
|
||||
void esp_set_assoc_ie(uint8_t *bssid, const u8 *ies, size_t ies_len, bool mdie)
|
||||
{
|
||||
#define ASSOC_IE_LEN 128
|
||||
uint8_t *ie, *pos;
|
||||
size_t len = ASSOC_IE_LEN;
|
||||
#if defined(CONFIG_WPA_11KV_SUPPORT) || defined(CONFIG_IEEE80211R)
|
||||
size_t ie_len;
|
||||
#endif /* defined(CONFIG_WPA_11KV_SUPPORT) || defined(CONFIG_IEEE80211R) */
|
||||
ie = os_malloc(ASSOC_IE_LEN + ies_len);
|
||||
if (!ie) {
|
||||
wpa_printf(MSG_ERROR, "failed to allocate ie");
|
||||
return;
|
||||
}
|
||||
pos = ie;
|
||||
#ifdef CONFIG_WPA_11KV_SUPPORT
|
||||
ie_len = get_extended_caps_ie(pos, len);
|
||||
pos += ie_len;
|
||||
len -= ie_len;
|
||||
ie_len = get_rm_enabled_ie(pos, len);
|
||||
pos += ie_len;
|
||||
len -= ie_len;
|
||||
#ifdef CONFIG_MBO
|
||||
ie_len = get_operating_class_ie(pos, len);
|
||||
pos += ie_len;
|
||||
len -= ie_len;
|
||||
ie_len = get_mbo_oce_assoc_ie(pos, len);
|
||||
pos += ie_len;
|
||||
len -= ie_len;
|
||||
#endif /* CONFIG_MBO */
|
||||
#endif /* CONFIG_WPA_11KV_SUPPORT */
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
if (mdie) {
|
||||
ie_len = add_mdie(bssid, pos, len);
|
||||
pos += ie_len;
|
||||
len -= ie_len;
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
if (ies_len) {
|
||||
os_memcpy(pos, ies, ies_len);
|
||||
pos += ies_len;
|
||||
len -= ies_len;
|
||||
}
|
||||
esp_wifi_set_appie_internal(WIFI_APPIE_ASSOC_REQ, ie, ASSOC_IE_LEN - len, 0);
|
||||
os_free(ie);
|
||||
#undef ASSOC_IE_LEN
|
||||
}
|
||||
#else
|
||||
void esp_set_assoc_ie(uint8_t *bssid, const u8 *ies, size_t ies_len, bool mdie) { }
|
||||
#endif /* defined(CONFIG_WPA_11KV_SUPPORT) || defined(CONFIG_IEEE80211R) || defined(CONFIG_WPA3_SAE) */
|
||||
|
@ -111,6 +111,7 @@ typedef struct {
|
||||
size_t num_pmkid;
|
||||
const u8 *pmkid;
|
||||
int mgmt_group_cipher;
|
||||
uint8_t rsnxe_capa;
|
||||
} wifi_wpa_ie_t;
|
||||
|
||||
struct wpa_funcs {
|
||||
@ -137,6 +138,7 @@ struct wpa_funcs {
|
||||
void (*wpa_config_done)(void);
|
||||
uint8_t *(*owe_build_dhie)(uint16_t group);
|
||||
int (*owe_process_assoc_resp)(const u8 *rsn_ie, size_t rsn_len, const uint8_t *dh_ie, size_t dh_len);
|
||||
int (*wpa_sta_set_ap_rsnxe)(const u8 *rsnxe, size_t rsnxe_ie_len);
|
||||
};
|
||||
|
||||
struct wpa2_funcs {
|
||||
@ -277,5 +279,7 @@ esp_err_t esp_wifi_remain_on_channel(uint8_t ifx, uint8_t type, uint8_t channel,
|
||||
bool esp_wifi_is_mbo_enabled_internal(uint8_t if_index);
|
||||
void esp_wifi_get_pmf_config_internal(wifi_pmf_config_t *pmf_cfg, uint8_t ifx);
|
||||
bool esp_wifi_is_ft_enabled_internal(uint8_t if_index);
|
||||
uint8_t esp_wifi_get_config_sae_pwe_h2e_internal(void);
|
||||
uint8_t esp_wifi_get_use_h2e_internal(void);
|
||||
|
||||
#endif /* _ESP_WIFI_DRIVER_H_ */
|
||||
|
@ -1,16 +1,8 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_WPA3_SAE
|
||||
|
||||
@ -19,6 +11,7 @@
|
||||
#include "esp_wifi_driver.h"
|
||||
#include "rsn_supp/wpa.h"
|
||||
|
||||
static struct sae_pt *g_sae_pt;
|
||||
static struct sae_data g_sae_data;
|
||||
static struct wpabuf *g_sae_token = NULL;
|
||||
static struct wpabuf *g_sae_commit = NULL;
|
||||
@ -30,7 +23,13 @@ static esp_err_t wpa3_build_sae_commit(u8 *bssid)
|
||||
int default_group = IANA_SECP256R1;
|
||||
u32 len = 0;
|
||||
u8 own_addr[ETH_ALEN];
|
||||
const u8 *pw;
|
||||
const u8 *pw = (const u8 *)esp_wifi_sta_get_prof_password_internal();
|
||||
struct wifi_ssid *ssid = esp_wifi_sta_get_prof_ssid_internal();
|
||||
uint8_t use_pt = esp_wifi_get_use_h2e_internal();
|
||||
|
||||
if (use_pt && !g_sae_pt) {
|
||||
g_sae_pt = sae_derive_pt(g_allowed_groups, ssid->ssid, ssid->len, pw, strlen((const char *)pw), NULL);
|
||||
}
|
||||
|
||||
if (wpa_sta_cur_pmksa_matches_akm()) {
|
||||
wpa_printf(MSG_INFO, "wpa3: Skip SAE and use cached PMK instead");
|
||||
@ -59,8 +58,16 @@ static esp_err_t wpa3_build_sae_commit(u8 *bssid)
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
pw = (const u8 *)esp_wifi_sta_get_prof_password_internal();
|
||||
if (sae_prepare_commit(own_addr, bssid, pw, strlen((const char *)pw), NULL, &g_sae_data) < 0) {
|
||||
if (use_pt &&
|
||||
sae_prepare_commit_pt(&g_sae_data, g_sae_pt,
|
||||
own_addr, bssid, NULL) < 0) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: failed to prepare SAE commit!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (!use_pt &&
|
||||
sae_prepare_commit(own_addr, bssid, pw,
|
||||
strlen((const char *)pw),
|
||||
&g_sae_data) < 0) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: failed to prepare SAE commit!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@ -128,6 +135,10 @@ void esp_wpa3_free_sae_data(void)
|
||||
g_sae_confirm = NULL;
|
||||
}
|
||||
sae_clear_data(&g_sae_data);
|
||||
if (g_sae_pt) {
|
||||
sae_deinit_pt(g_sae_pt);
|
||||
g_sae_pt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static u8 *wpa3_build_sae_msg(u8 *bssid, u32 sae_msg_type, size_t *sae_msg_len)
|
||||
@ -167,11 +178,23 @@ static int wpa3_parse_sae_commit(u8 *buf, u32 len, u16 status)
|
||||
if (status == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ) {
|
||||
if (g_sae_token)
|
||||
wpabuf_free(g_sae_token);
|
||||
g_sae_token = wpabuf_alloc_copy(buf + 2, len - 2);
|
||||
if (g_sae_data.h2e) {
|
||||
if ((buf[2] != WLAN_EID_EXTENSION) ||
|
||||
(buf[3] == 0) ||
|
||||
(buf[3] > len - 4) ||
|
||||
(buf[4] != WLAN_EID_EXT_ANTI_CLOGGING_TOKEN)) {
|
||||
wpa_printf(MSG_ERROR, "Invalid SAE anti-clogging token container header");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
g_sae_token = wpabuf_alloc_copy(buf + 5, len - 5);
|
||||
} else {
|
||||
g_sae_token = wpabuf_alloc_copy(buf + 2, len - 2);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
ret = sae_parse_commit(&g_sae_data, buf, len, NULL, 0, g_allowed_groups);
|
||||
ret = sae_parse_commit(&g_sae_data, buf, len, NULL, 0, g_allowed_groups,
|
||||
status == WLAN_STATUS_SAE_HASH_TO_ELEMENT);
|
||||
if (ret) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: could not parse commit(%d)", ret);
|
||||
return ret;
|
||||
|
@ -220,6 +220,7 @@ int wpa_parse_wpa_ie_wrapper(const u8 *wpa_ie, size_t wpa_ie_len, wifi_wpa_ie_t
|
||||
data->capabilities = ie.capabilities;
|
||||
data->pmkid = ie.pmkid;
|
||||
data->mgmt_group_cipher = cipher_type_map_supp_to_public(ie.mgmt_group_cipher);
|
||||
data->rsnxe_capa = ie.rsnxe_capa;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -341,6 +342,7 @@ int esp_supplicant_init(void)
|
||||
wpa_cb->wpa_config_bss = NULL;//wpa_config_bss;
|
||||
wpa_cb->wpa_michael_mic_failure = wpa_michael_mic_failure;
|
||||
wpa_cb->wpa_config_done = wpa_config_done;
|
||||
wpa_cb->wpa_sta_set_ap_rsnxe = wpa_sm_set_ap_rsnxe;
|
||||
|
||||
esp_wifi_register_wpa3_cb(wpa_cb);
|
||||
#ifdef CONFIG_OWE_STA
|
||||
|
@ -157,6 +157,7 @@
|
||||
#define WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL 99
|
||||
#define WLAN_STATUS_ASSOC_DENIED_NO_VHT 104
|
||||
#define WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER 123
|
||||
#define WLAN_STATUS_SAE_HASH_TO_ELEMENT 126
|
||||
|
||||
/* Reason codes (IEEE Std 802.11-2016, 9.4.1.7, Table 9-45) */
|
||||
#define WLAN_REASON_UNSPECIFIED 1
|
||||
@ -228,6 +229,7 @@
|
||||
#define WLAN_EID_FILS_INDICATION 240
|
||||
#define WLAN_EID_DILS 241
|
||||
#define WLAN_EID_FRAGMENT 242
|
||||
#define WLAN_EID_RSNX 244
|
||||
#define WLAN_EID_EXTENSION 255
|
||||
|
||||
/* Element ID Extension (EID 255) values */
|
||||
@ -249,6 +251,12 @@
|
||||
#define WLAN_EID_EXT_PASSWORD_IDENTIFIER 33
|
||||
#define WLAN_EID_EXT_HE_CAPABILITIES 35
|
||||
#define WLAN_EID_EXT_HE_OPERATION 36
|
||||
#define WLAN_EID_EXT_REJECTED_GROUPS 92
|
||||
#define WLAN_EID_EXT_ANTI_CLOGGING_TOKEN 93
|
||||
|
||||
/* Extended RSN Capabilities */
|
||||
/* bits 0-3: Field length (n-1) */
|
||||
#define WLAN_RSNX_CAPAB_SAE_H2E 5
|
||||
|
||||
#define WLAN_EXT_CAPAB_BSS_TRANSITION 19
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -21,8 +21,9 @@
|
||||
#define SAE_KEYSEED_KEY_LEN 32
|
||||
#define SAE_MAX_PRIME_LEN 512
|
||||
#define SAE_MAX_ECC_PRIME_LEN 66
|
||||
#define SAE_COMMIT_MAX_LEN (2 + 3 * SAE_MAX_PRIME_LEN)
|
||||
#define SAE_CONFIRM_MAX_LEN (2 + SAE_MAX_PRIME_LEN)
|
||||
#define SAE_MAX_HASH_LEN 64
|
||||
#define SAE_COMMIT_MAX_LEN (2 + 3 * SAE_MAX_PRIME_LEN + 255)
|
||||
#define SAE_CONFIRM_MAX_LEN (2 + SAE_MAX_HASH_LEN)
|
||||
|
||||
/* Special value returned by sae_parse_commit() */
|
||||
#define SAE_SILENTLY_DISCARD 65535
|
||||
@ -45,6 +46,20 @@ struct sae_temporary_data {
|
||||
struct crypto_bignum *prime_buf;
|
||||
struct crypto_bignum *order_buf;
|
||||
char *pw_id;
|
||||
int order_len;
|
||||
struct wpabuf *own_rejected_groups;
|
||||
struct wpabuf *peer_rejected_groups;
|
||||
unsigned int own_addr_higher:1;
|
||||
};
|
||||
|
||||
struct sae_pt {
|
||||
struct sae_pt *next;
|
||||
int group;
|
||||
struct crypto_ec *ec;
|
||||
struct crypto_ec_point *ecc_pt;
|
||||
|
||||
const struct dh_group *dh;
|
||||
struct crypto_bignum *ffc_pt;
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -66,6 +81,8 @@ struct sae_data {
|
||||
unsigned int sync; /* protocol instance variable: Sync */
|
||||
u16 rc; /* protocol instance variable: Rc (received send-confirm) */
|
||||
struct sae_temporary_data *tmp;
|
||||
struct crypto_bignum *peer_commit_scalar_accepted;
|
||||
unsigned int h2e:1;
|
||||
};
|
||||
|
||||
int sae_set_group(struct sae_data *sae, int group);
|
||||
@ -74,16 +91,32 @@ void sae_clear_data(struct sae_data *sae);
|
||||
|
||||
int sae_prepare_commit(const u8 *addr1, const u8 *addr2,
|
||||
const u8 *password, size_t password_len,
|
||||
const char *identifier, struct sae_data *sae);
|
||||
struct sae_data *sae);
|
||||
int sae_prepare_commit_pt(struct sae_data *sae, struct sae_pt *pt,
|
||||
const u8 *addr1, const u8 *addr2,
|
||||
int *rejected_groups);
|
||||
int sae_process_commit(struct sae_data *sae);
|
||||
int sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
|
||||
const struct wpabuf *token, const char *identifier);
|
||||
const struct wpabuf *token, const char *identifier);
|
||||
u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
|
||||
const u8 **token, size_t *token_len, int *allowed_groups);
|
||||
const u8 **token, size_t *token_len, int *allowed_groups,
|
||||
int h2e);
|
||||
int sae_write_confirm(struct sae_data *sae, struct wpabuf *buf);
|
||||
int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len);
|
||||
u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group);
|
||||
const char * sae_state_txt(enum sae_state state);
|
||||
size_t sae_ecc_prime_len_2_hash_len(size_t prime_len);
|
||||
size_t sae_ffc_prime_len_2_hash_len(size_t prime_len);
|
||||
struct sae_pt * sae_derive_pt(int *groups, const u8 *ssid, size_t ssid_len,
|
||||
const u8 *password, size_t password_len,
|
||||
const char *identifier);
|
||||
struct crypto_ec_point *
|
||||
sae_derive_pwe_from_pt_ecc(const struct sae_pt *pt,
|
||||
const u8 *addr1, const u8 *addr2);
|
||||
struct crypto_bignum *
|
||||
sae_derive_pwe_from_pt_ffc(const struct sae_pt *pt,
|
||||
const u8 *addr1, const u8 *addr2);
|
||||
void sae_deinit_pt(struct sae_pt *pt);
|
||||
|
||||
#endif /* SAE_H */
|
||||
#endif /* CONFIG_WPA3_SAE */
|
||||
|
@ -365,6 +365,25 @@ int wpa_cipher_valid_mgmt_group(int cipher)
|
||||
cipher == WPA_CIPHER_BIP_GMAC_256;
|
||||
}
|
||||
|
||||
int wpa_parse_wpa_ie_rsnxe(const u8 *rsnxe_ie, size_t rsnxe_ie_len,
|
||||
struct wpa_ie_data *data)
|
||||
{
|
||||
uint8_t rsnxe_capa = 0;
|
||||
uint8_t sae_pwe = esp_wifi_get_config_sae_pwe_h2e_internal();
|
||||
memset(data, 0, sizeof(*data));
|
||||
|
||||
if (rsnxe_ie_len < 1) {
|
||||
return -1;
|
||||
}
|
||||
rsnxe_capa = rsnxe_ie[2];
|
||||
if (sae_pwe == 1 && !(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_H2E))){
|
||||
wpa_printf(MSG_ERROR, "SAE H2E required, but not supported by the AP");
|
||||
return -1;
|
||||
}
|
||||
data->rsnxe_capa = rsnxe_capa;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* wpa_parse_wpa_ie_rsn - Parse RSN IE
|
||||
* @rsn_ie: Buffer containing RSN IE
|
||||
@ -941,7 +960,8 @@ int wpa_compare_rsn_ie(int ft_initial_assoc,
|
||||
ie1d.group_cipher == ie2d.group_cipher &&
|
||||
ie1d.key_mgmt == ie2d.key_mgmt &&
|
||||
ie1d.capabilities == ie2d.capabilities &&
|
||||
ie1d.mgmt_group_cipher == ie2d.mgmt_group_cipher)
|
||||
ie1d.mgmt_group_cipher == ie2d.mgmt_group_cipher &&
|
||||
ie1d.rsnxe_capa == ie2d.rsnxe_capa)
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
|
@ -337,6 +337,7 @@ struct wpa_ie_data {
|
||||
size_t num_pmkid;
|
||||
const u8 *pmkid;
|
||||
int mgmt_group_cipher;
|
||||
uint8_t rsnxe_capa;
|
||||
};
|
||||
|
||||
struct rsn_sppamsdu_sup {
|
||||
@ -372,6 +373,8 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
|
||||
struct wpa_ie_data *data);
|
||||
int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
|
||||
struct wpa_ie_data *data);
|
||||
int wpa_parse_wpa_ie_rsnxe(const u8 *rsnxe_ie, size_t rsnxe_ie_len,
|
||||
struct wpa_ie_data *data);
|
||||
|
||||
int wpa_compare_rsn_ie(int ft_initial_assoc,
|
||||
const u8 *ie1, size_t ie1len,
|
||||
|
@ -654,6 +654,26 @@ int crypto_bignum_mulmod(const struct crypto_bignum *a,
|
||||
const struct crypto_bignum *c,
|
||||
struct crypto_bignum *d);
|
||||
|
||||
/**
|
||||
* crypto_bignum_sqrmod - c = a^2 (mod b)
|
||||
* @a: Bignum
|
||||
* @b: Bignum
|
||||
* @c: Bignum; used to store the result of a^2 % b
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_bignum_sqrmod(const struct crypto_bignum *a,
|
||||
const struct crypto_bignum *b,
|
||||
struct crypto_bignum *c);
|
||||
/**
|
||||
* crypto_bignum_rshift - r = a >> n
|
||||
* @a: Bignum
|
||||
* @n: Number of bits
|
||||
* @r: Bignum; used to store the result of a >> n
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
|
||||
struct crypto_bignum *r);
|
||||
|
||||
/**
|
||||
* crypto_bignum_cmp - Compare two bignums
|
||||
* @a: Bignum
|
||||
@ -730,6 +750,13 @@ size_t crypto_ec_prime_len(struct crypto_ec *e);
|
||||
*/
|
||||
size_t crypto_ec_prime_len_bits(struct crypto_ec *e);
|
||||
|
||||
/**
|
||||
* crypto_ec_order_len - Get length of the order in octets
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* Returns: Length of the order defining the group
|
||||
*/
|
||||
size_t crypto_ec_order_len(struct crypto_ec *e);
|
||||
|
||||
/**
|
||||
* crypto_ec_get_prime - Get prime defining an EC group
|
||||
* @e: EC context from crypto_ec_init()
|
||||
@ -750,6 +777,14 @@ const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e);
|
||||
* Internal data structure for EC implementation to represent a point. The
|
||||
* contents is specific to the used crypto library.
|
||||
*/
|
||||
|
||||
/**
|
||||
* crypto_ec_get_b - Get 'b' coeffiecient of an EC group's curve
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* Returns: 'b' coefficient (bignum) of the group
|
||||
*/
|
||||
const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e);
|
||||
|
||||
struct crypto_ec_point;
|
||||
|
||||
/**
|
||||
|
@ -650,6 +650,8 @@ void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
|
||||
struct wpa_eapol_ie_parse ie;
|
||||
struct wpa_ptk *ptk;
|
||||
int res;
|
||||
u8 *kde, *kde_buf = NULL;
|
||||
size_t kde_len;
|
||||
|
||||
wpa_sm_set_state(WPA_FIRST_HALF_4WAY_HANDSHAKE);
|
||||
|
||||
@ -705,16 +707,30 @@ void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
|
||||
sm->tptk_set = 1;
|
||||
sm->ptk_set = 0;
|
||||
sm->key_install = true;
|
||||
kde = sm->assoc_wpa_ie;
|
||||
kde_len = sm->assoc_wpa_ie_len;
|
||||
kde_buf = os_malloc(kde_len +
|
||||
sm->assoc_rsnxe_len);
|
||||
if (!kde_buf)
|
||||
goto failed;
|
||||
os_memcpy(kde_buf, kde, kde_len);
|
||||
kde = kde_buf;
|
||||
|
||||
if (sm->assoc_rsnxe && sm->assoc_rsnxe_len) {
|
||||
os_memcpy(kde + kde_len, sm->assoc_rsnxe, sm->assoc_rsnxe_len);
|
||||
kde_len += sm->assoc_rsnxe_len;
|
||||
}
|
||||
|
||||
if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce,
|
||||
sm->assoc_wpa_ie, sm->assoc_wpa_ie_len,
|
||||
ptk))
|
||||
kde, kde_len, ptk))
|
||||
goto failed;
|
||||
|
||||
os_free(kde_buf);
|
||||
memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN);
|
||||
return;
|
||||
|
||||
failed:
|
||||
os_free(kde_buf);
|
||||
wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
|
||||
}
|
||||
|
||||
@ -1104,6 +1120,22 @@ static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sm->proto == WPA_PROTO_RSN &&
|
||||
((sm->ap_rsnxe && !ie->rsnxe) ||
|
||||
(!sm->ap_rsnxe && ie->rsnxe) ||
|
||||
(sm->ap_rsnxe && ie->rsnxe &&
|
||||
(sm->ap_rsnxe_len != ie->rsnxe_len ||
|
||||
os_memcmp(sm->ap_rsnxe, ie->rsnxe, sm->ap_rsnxe_len) != 0)))) {
|
||||
wpa_printf(MSG_INFO,
|
||||
"WPA: RSNXE mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4");
|
||||
wpa_hexdump(MSG_INFO, "RSNXE in Beacon/ProbeResp",
|
||||
sm->ap_rsnxe, sm->ap_rsnxe_len);
|
||||
wpa_hexdump(MSG_INFO, "RSNXE in EAPOL-Key msg 3/4",
|
||||
ie->rsnxe, ie->rsnxe_len);
|
||||
wpa_sm_deauthenticate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2209,6 +2241,8 @@ void wpa_sm_deinit(void)
|
||||
{
|
||||
struct wpa_sm *sm = &gWpaSm;
|
||||
pmksa_cache_deinit(sm->pmksa);
|
||||
os_free(sm->ap_rsnxe);
|
||||
os_free(sm->assoc_rsnxe);
|
||||
}
|
||||
|
||||
|
||||
@ -2263,6 +2297,8 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher,
|
||||
int res = 0;
|
||||
struct wpa_sm *sm = &gWpaSm;
|
||||
bool use_pmk_cache = true;
|
||||
u8 assoc_rsnxe[20];
|
||||
size_t assoc_rsnxe_len = sizeof(assoc_rsnxe);
|
||||
|
||||
/* Incase AP has changed it's SSID, don't try with PMK caching for SAE connection */
|
||||
/* Ideally we should use network_ctx for this purpose however currently network profile block
|
||||
@ -2357,7 +2393,14 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher,
|
||||
if (res < 0)
|
||||
return -1;
|
||||
sm->assoc_wpa_ie_len = res;
|
||||
esp_set_assoc_ie((uint8_t *)bssid, NULL, 0, true);
|
||||
res = wpa_gen_rsnxe(sm ,assoc_rsnxe, assoc_rsnxe_len);
|
||||
if (res < 0)
|
||||
return -1;
|
||||
assoc_rsnxe_len = res;
|
||||
res = wpa_sm_set_assoc_rsnxe(sm, assoc_rsnxe, assoc_rsnxe_len);
|
||||
if (res < 0)
|
||||
return -1;
|
||||
esp_set_assoc_ie((uint8_t *)bssid, assoc_rsnxe, assoc_rsnxe_len, true);
|
||||
os_memset(sm->ssid, 0, sizeof(sm->ssid));
|
||||
os_memcpy(sm->ssid, ssid, ssid_len);
|
||||
sm->ssid_len = ssid_len;
|
||||
@ -2611,6 +2654,52 @@ struct wpa_sm * get_wpa_sm(void)
|
||||
return &gWpaSm;
|
||||
}
|
||||
|
||||
int wpa_sm_set_ap_rsnxe(const u8 *ie, size_t len)
|
||||
{
|
||||
struct wpa_sm *sm = &gWpaSm;
|
||||
if (!sm)
|
||||
return -1;
|
||||
|
||||
os_free(sm->ap_rsnxe);
|
||||
if (!ie || len == 0) {
|
||||
wpa_hexdump(MSG_DEBUG, "WPA: set AP RSNXE", ie, len);
|
||||
sm->ap_rsnxe = NULL;
|
||||
sm->ap_rsnxe_len = 0;
|
||||
} else {
|
||||
wpa_hexdump(MSG_DEBUG, "WPA: set AP RSNXE", ie, len);
|
||||
sm->ap_rsnxe = os_memdup(ie, len);
|
||||
if (!sm->ap_rsnxe)
|
||||
return -1;
|
||||
|
||||
sm->ap_rsnxe_len = len;
|
||||
}
|
||||
|
||||
sm->sae_pwe = esp_wifi_get_config_sae_pwe_h2e_internal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len)
|
||||
{
|
||||
if (!sm)
|
||||
return -1;
|
||||
|
||||
os_free(sm->assoc_rsnxe);
|
||||
if (!ie || len == 0) {
|
||||
sm->assoc_rsnxe = NULL;
|
||||
sm->assoc_rsnxe_len = 0;
|
||||
} else {
|
||||
wpa_hexdump(MSG_DEBUG, "RSN: set own RSNXE", ie, len);
|
||||
sm->assoc_rsnxe = os_memdup(ie, len);
|
||||
if (!sm->assoc_rsnxe)
|
||||
return -1;
|
||||
|
||||
sm->assoc_rsnxe_len = len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OWE_STA
|
||||
struct wpabuf *owe_build_assoc_req(struct wpa_sm *sm, u16 group)
|
||||
{
|
||||
|
@ -54,6 +54,10 @@ int wpa_sm_set_key(struct install_key *sm, enum wpa_alg alg,
|
||||
u8 *key, size_t key_len,
|
||||
enum key_flag key_flag);
|
||||
|
||||
int wpa_sm_set_ap_rsnxe(const u8 *ie, size_t len);
|
||||
|
||||
int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len);
|
||||
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
|
||||
int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len);
|
||||
|
@ -48,11 +48,14 @@ struct wpa_sm {
|
||||
void *network_ctx;
|
||||
|
||||
int rsn_enabled; /* Whether RSN is enabled in configuration */
|
||||
int sae_pwe; /* SAE PWE generation options */
|
||||
|
||||
int countermeasures; /*TKIP countermeasures state flag, 1:in countermeasures state*/
|
||||
|
||||
u8 *assoc_wpa_ie; /* Own WPA/RSN IE from (Re)AssocReq */
|
||||
size_t assoc_wpa_ie_len;
|
||||
u8 *assoc_rsnxe; /* Own RSNXE from (Re)AssocReq */
|
||||
size_t assoc_rsnxe_len;
|
||||
|
||||
u8 eapol_version;
|
||||
|
||||
@ -64,8 +67,8 @@ struct wpa_sm {
|
||||
unsigned int proto;
|
||||
enum wpa_states wpa_state;
|
||||
|
||||
u8 *ap_wpa_ie, *ap_rsn_ie;
|
||||
size_t ap_wpa_ie_len, ap_rsn_ie_len;
|
||||
u8 *ap_wpa_ie, *ap_rsn_ie, *ap_rsnxe;
|
||||
size_t ap_wpa_ie_len, ap_rsn_ie_len, ap_rsnxe_len;
|
||||
|
||||
bool key_install;
|
||||
|
||||
|
@ -35,6 +35,8 @@ int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
|
||||
{
|
||||
if (wpa_ie_len >= 1 && wpa_ie[0] == WLAN_EID_RSN) {
|
||||
return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
|
||||
} else if (wpa_ie_len >=1 && wpa_ie[0] == WLAN_EID_RSNX){
|
||||
return wpa_parse_wpa_ie_rsnxe(wpa_ie, wpa_ie_len, data);
|
||||
} else if (wpa_ie[0] == WLAN_EID_WAPI) {
|
||||
return 0;
|
||||
}
|
||||
@ -293,6 +295,34 @@ int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len)
|
||||
}
|
||||
|
||||
|
||||
int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len)
|
||||
{
|
||||
u8 *pos = rsnxe;
|
||||
u16 capab = 0;
|
||||
size_t flen;
|
||||
|
||||
if (wpa_key_mgmt_sae(sm->key_mgmt) &&
|
||||
(sm->sae_pwe == 1 || sm->sae_pwe == 2)) {
|
||||
capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E);
|
||||
}
|
||||
|
||||
flen = (capab & 0xff00) ? 2 : 1;
|
||||
if (!capab)
|
||||
return 0; /* no supported extended RSN capabilities */
|
||||
if (rsnxe_len < 2 + flen)
|
||||
return -1;
|
||||
capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
|
||||
|
||||
*pos++ = WLAN_EID_RSNX;
|
||||
*pos++ = flen;
|
||||
*pos++ = capab & 0x00ff;
|
||||
capab >>= 8;
|
||||
if (capab)
|
||||
*pos++ = capab;
|
||||
|
||||
return pos - rsnxe;
|
||||
}
|
||||
|
||||
/**
|
||||
* wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
|
||||
* @pos: Pointer to the IE header
|
||||
@ -393,6 +423,11 @@ int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
|
||||
ie->rsn_ie_len = pos[1] + 2;
|
||||
wpa_hexdump(MSG_DEBUG, "WPA: RSN IE in EAPOL-Key",
|
||||
ie->rsn_ie, ie->rsn_ie_len);
|
||||
} else if (*pos == WLAN_EID_RSNX) {
|
||||
ie->rsnxe = pos;
|
||||
ie->rsnxe_len = pos[1] + 2;
|
||||
wpa_hexdump(MSG_DEBUG, "WPA: RSNXE in EAPOL-Key",
|
||||
ie->rsnxe, ie->rsnxe_len);
|
||||
} else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
|
||||
ret = wpa_parse_generic(pos, end, ie);
|
||||
if (ret < 0)
|
||||
|
@ -37,12 +37,14 @@ struct wpa_eapol_ie_parse {
|
||||
const u8 *reassoc_deadline;
|
||||
const u8 *key_lifetime;
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
const u8 *rsnxe;
|
||||
size_t rsnxe_len;
|
||||
};
|
||||
|
||||
int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
|
||||
struct wpa_eapol_ie_parse *ie);
|
||||
int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len);
|
||||
|
||||
int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len);
|
||||
int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
|
||||
struct wpa_ie_data *data);
|
||||
|
||||
|
191
components/wpa_supplicant/src/utils/const_time.h
Normal file
191
components/wpa_supplicant/src/utils/const_time.h
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Helper functions for constant time operations
|
||||
* Copyright (c) 2019, The Linux Foundation
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*
|
||||
* These helper functions can be used to implement logic that needs to minimize
|
||||
* externally visible differences in execution path by avoiding use of branches,
|
||||
* avoiding early termination or other time differences, and forcing same memory
|
||||
* access pattern regardless of values.
|
||||
*/
|
||||
|
||||
#ifndef CONST_TIME_H
|
||||
#define CONST_TIME_H
|
||||
|
||||
|
||||
#if defined(__clang__)
|
||||
#define NO_UBSAN_UINT_OVERFLOW \
|
||||
__attribute__((no_sanitize("unsigned-integer-overflow")))
|
||||
#else
|
||||
#define NO_UBSAN_UINT_OVERFLOW
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* const_time_fill_msb - Fill all bits with MSB value
|
||||
* @val: Input value
|
||||
* Returns: Value with all the bits set to the MSB of the input val
|
||||
*/
|
||||
static inline unsigned int const_time_fill_msb(unsigned int val)
|
||||
{
|
||||
/* Move the MSB to LSB and multiple by -1 to fill in all bits. */
|
||||
return (val >> (sizeof(val) * 8 - 1)) * ~0U;
|
||||
}
|
||||
|
||||
|
||||
/* Returns: -1 if val is zero; 0 if val is not zero */
|
||||
static inline unsigned int const_time_is_zero(unsigned int val)
|
||||
NO_UBSAN_UINT_OVERFLOW
|
||||
{
|
||||
/* Set MSB to 1 for 0 and fill rest of bits with the MSB value */
|
||||
return const_time_fill_msb(~val & (val - 1));
|
||||
}
|
||||
|
||||
|
||||
/* Returns: -1 if a == b; 0 if a != b */
|
||||
static inline unsigned int const_time_eq(unsigned int a, unsigned int b)
|
||||
{
|
||||
return const_time_is_zero(a ^ b);
|
||||
}
|
||||
|
||||
|
||||
/* Returns: -1 if a == b; 0 if a != b */
|
||||
static inline u8 const_time_eq_u8(unsigned int a, unsigned int b)
|
||||
{
|
||||
return (u8) const_time_eq(a, b);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* const_time_eq_bin - Constant time memory comparison
|
||||
* @a: First buffer to compare
|
||||
* @b: Second buffer to compare
|
||||
* @len: Number of octets to compare
|
||||
* Returns: -1 if buffers are equal, 0 if not
|
||||
*
|
||||
* This function is meant for comparing passwords or hash values where
|
||||
* difference in execution time or memory access pattern could provide external
|
||||
* observer information about the location of the difference in the memory
|
||||
* buffers. The return value does not behave like memcmp(), i.e.,
|
||||
* const_time_eq_bin() cannot be used to sort items into a defined order. Unlike
|
||||
* memcmp(), the execution time of const_time_eq_bin() does not depend on the
|
||||
* contents of the compared memory buffers, but only on the total compared
|
||||
* length.
|
||||
*/
|
||||
static inline unsigned int const_time_eq_bin(const void *a, const void *b,
|
||||
size_t len)
|
||||
{
|
||||
const u8 *aa = a;
|
||||
const u8 *bb = b;
|
||||
size_t i;
|
||||
u8 res = 0;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
res |= aa[i] ^ bb[i];
|
||||
|
||||
return const_time_is_zero(res);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* const_time_select - Constant time unsigned int selection
|
||||
* @mask: 0 (false) or -1 (true) to identify which value to select
|
||||
* @true_val: Value to select for the true case
|
||||
* @false_val: Value to select for the false case
|
||||
* Returns: true_val if mask == -1, false_val if mask == 0
|
||||
*/
|
||||
static inline unsigned int const_time_select(unsigned int mask,
|
||||
unsigned int true_val,
|
||||
unsigned int false_val)
|
||||
{
|
||||
return (mask & true_val) | (~mask & false_val);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* const_time_select_int - Constant time int selection
|
||||
* @mask: 0 (false) or -1 (true) to identify which value to select
|
||||
* @true_val: Value to select for the true case
|
||||
* @false_val: Value to select for the false case
|
||||
* Returns: true_val if mask == -1, false_val if mask == 0
|
||||
*/
|
||||
static inline int const_time_select_int(unsigned int mask, int true_val,
|
||||
int false_val)
|
||||
{
|
||||
return (int) const_time_select(mask, (unsigned int) true_val,
|
||||
(unsigned int) false_val);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* const_time_select_u8 - Constant time u8 selection
|
||||
* @mask: 0 (false) or -1 (true) to identify which value to select
|
||||
* @true_val: Value to select for the true case
|
||||
* @false_val: Value to select for the false case
|
||||
* Returns: true_val if mask == -1, false_val if mask == 0
|
||||
*/
|
||||
static inline u8 const_time_select_u8(u8 mask, u8 true_val, u8 false_val)
|
||||
{
|
||||
return (u8) const_time_select(mask, true_val, false_val);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* const_time_select_s8 - Constant time s8 selection
|
||||
* @mask: 0 (false) or -1 (true) to identify which value to select
|
||||
* @true_val: Value to select for the true case
|
||||
* @false_val: Value to select for the false case
|
||||
* Returns: true_val if mask == -1, false_val if mask == 0
|
||||
*/
|
||||
static inline s8 const_time_select_s8(u8 mask, s8 true_val, s8 false_val)
|
||||
{
|
||||
return (s8) const_time_select(mask, (unsigned int) true_val,
|
||||
(unsigned int) false_val);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* const_time_select_bin - Constant time binary buffer selection copy
|
||||
* @mask: 0 (false) or -1 (true) to identify which value to copy
|
||||
* @true_val: Buffer to copy for the true case
|
||||
* @false_val: Buffer to copy for the false case
|
||||
* @len: Number of octets to copy
|
||||
* @dst: Destination buffer for the copy
|
||||
*
|
||||
* This function copies the specified buffer into the destination buffer using
|
||||
* operations with identical memory access pattern regardless of which buffer
|
||||
* is being copied.
|
||||
*/
|
||||
static inline void const_time_select_bin(u8 mask, const u8 *true_val,
|
||||
const u8 *false_val, size_t len,
|
||||
u8 *dst)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
dst[i] = const_time_select_u8(mask, true_val[i], false_val[i]);
|
||||
}
|
||||
|
||||
|
||||
static inline int const_time_memcmp(const void *a, const void *b, size_t len)
|
||||
{
|
||||
const u8 *aa = a;
|
||||
const u8 *bb = b;
|
||||
int diff, res = 0;
|
||||
unsigned int mask;
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
do {
|
||||
len--;
|
||||
diff = (int) aa[len] - (int) bb[len];
|
||||
mask = const_time_is_zero((unsigned int) diff);
|
||||
res = const_time_select_int(mask, res, diff);
|
||||
} while (len);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* CONST_TIME_H */
|
@ -74,7 +74,7 @@ TEST_CASE("Test SAE functionality with ECC group", "[wpa3_sae]")
|
||||
|
||||
TEST_ASSERT(sae_set_group(&sae, IANA_SECP256R1) == 0);
|
||||
|
||||
TEST_ASSERT(sae_prepare_commit(addr1, addr2, pwd, strlen((const char *)pwd), NULL, &sae) == 0);
|
||||
TEST_ASSERT(sae_prepare_commit(addr1, addr2, pwd, strlen((const char *)pwd), &sae) == 0);
|
||||
|
||||
buf = wpabuf_alloc2(SAE_COMMIT_MAX_LEN);
|
||||
|
||||
@ -84,7 +84,7 @@ TEST_CASE("Test SAE functionality with ECC group", "[wpa3_sae]")
|
||||
|
||||
/* Parsing commit created by self will be detected as reflection attack*/
|
||||
TEST_ASSERT(sae_parse_commit(&sae,
|
||||
wpabuf_mhead(buf), buf->used, NULL, 0, default_groups) == SAE_SILENTLY_DISCARD);
|
||||
wpabuf_mhead(buf), buf->used, NULL, 0, default_groups, 0) == SAE_SILENTLY_DISCARD);
|
||||
|
||||
wpabuf_free2(buf);
|
||||
sae_clear_temp_data(&sae);
|
||||
@ -112,10 +112,10 @@ TEST_CASE("Test SAE functionality with ECC group", "[wpa3_sae]")
|
||||
TEST_ASSERT(sae_set_group(&sae2, IANA_SECP256R1) == 0);
|
||||
|
||||
/* STA1 prepares for commit*/
|
||||
TEST_ASSERT(sae_prepare_commit(addr1, addr2, pwd, strlen((const char *)pwd), NULL, &sae1) == 0);
|
||||
TEST_ASSERT(sae_prepare_commit(addr1, addr2, pwd, strlen((const char *)pwd), &sae1) == 0);
|
||||
|
||||
/* STA2 prepares for commit*/
|
||||
TEST_ASSERT(sae_prepare_commit(addr2, addr1, pwd, strlen((const char *)pwd), NULL, &sae2) == 0);
|
||||
TEST_ASSERT(sae_prepare_commit(addr2, addr1, pwd, strlen((const char *)pwd), &sae2) == 0);
|
||||
|
||||
/* STA1 creates commit msg buffer*/
|
||||
buf1 = wpabuf_alloc2(SAE_COMMIT_MAX_LEN);
|
||||
@ -135,11 +135,11 @@ TEST_CASE("Test SAE functionality with ECC group", "[wpa3_sae]")
|
||||
|
||||
/* STA1 parses STA2 commit*/
|
||||
TEST_ASSERT(sae_parse_commit(&sae1,
|
||||
wpabuf_mhead(buf2), buf2->used, NULL, 0, default_groups) == 0);
|
||||
wpabuf_mhead(buf2), buf2->used, NULL, 0, default_groups, 0) == 0);
|
||||
|
||||
/* STA2 parses STA1 commit*/
|
||||
TEST_ASSERT(sae_parse_commit(&sae2,
|
||||
wpabuf_mhead(buf1), buf1->used, NULL, 0, default_groups) == 0);
|
||||
wpabuf_mhead(buf1), buf1->used, NULL, 0, default_groups, 0) == 0);
|
||||
|
||||
/* STA1 processes commit*/
|
||||
TEST_ASSERT(sae_process_commit(&sae1) == 0);
|
||||
@ -200,10 +200,10 @@ TEST_CASE("Test SAE functionality with ECC group", "[wpa3_sae]")
|
||||
TEST_ASSERT(sae_set_group(&sae2, IANA_SECP256R1) == 0);
|
||||
|
||||
/* STA1 prepares for commit*/
|
||||
TEST_ASSERT(sae_prepare_commit(addr1, addr2, pwd1, strlen((const char *)pwd1), NULL, &sae1) == 0);
|
||||
TEST_ASSERT(sae_prepare_commit(addr1, addr2, pwd1, strlen((const char *)pwd1), &sae1) == 0);
|
||||
|
||||
/* STA2 prepares for commit*/
|
||||
TEST_ASSERT(sae_prepare_commit(addr2, addr1, pwd2, strlen((const char *)pwd2), NULL, &sae2) == 0);
|
||||
TEST_ASSERT(sae_prepare_commit(addr2, addr1, pwd2, strlen((const char *)pwd2), &sae2) == 0);
|
||||
|
||||
/* STA1 creates commit msg buffer*/
|
||||
buf1 = wpabuf_alloc2(SAE_COMMIT_MAX_LEN);
|
||||
@ -220,11 +220,11 @@ TEST_CASE("Test SAE functionality with ECC group", "[wpa3_sae]")
|
||||
|
||||
/* STA1 parses STA2 commit*/
|
||||
TEST_ASSERT(sae_parse_commit(&sae1,
|
||||
wpabuf_mhead(buf2), buf2->used, NULL, 0, default_groups) == 0);
|
||||
wpabuf_mhead(buf2), buf2->used, NULL, 0, default_groups, 0) == 0);
|
||||
|
||||
/* STA2 parses STA1 commit*/
|
||||
TEST_ASSERT(sae_parse_commit(&sae2,
|
||||
wpabuf_mhead(buf1), buf1->used, NULL, 0, default_groups) == 0);
|
||||
wpabuf_mhead(buf1), buf1->used, NULL, 0, default_groups, 0) == 0);
|
||||
|
||||
/* STA1 processes commit*/
|
||||
TEST_ASSERT(sae_process_commit(&sae1) == 0);
|
||||
|
@ -115,6 +115,7 @@ void wifi_init_sta(void)
|
||||
* However these modes are deprecated and not advisable to be used. Incase your Access point
|
||||
* doesn't support WPA2, these mode can be enabled by commenting below line */
|
||||
.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
|
||||
.sae_pwe_h2e = 2,
|
||||
},
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
|
||||
|
@ -1500,7 +1500,6 @@ components/wifi_provisioning/src/wifi_config.c
|
||||
components/wifi_provisioning/src/wifi_provisioning_priv.h
|
||||
components/wifi_provisioning/src/wifi_scan.c
|
||||
components/wpa_supplicant/esp_supplicant/src/esp_scan_i.h
|
||||
components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c
|
||||
components/wpa_supplicant/esp_supplicant/src/esp_wpa3_i.h
|
||||
components/wpa_supplicant/esp_supplicant/src/esp_wpa_err.h
|
||||
components/wpa_supplicant/include/utils/wpa_debug.h
|
||||
|
Loading…
Reference in New Issue
Block a user