esp_wifi: WPA3 SAE H2E support for station

Mandate sta threshold wpa3 for ssid after receiving transition disable
bit from AP
This commit is contained in:
Shreyas Sheth 2022-07-25 10:02:05 +05:30
parent 4c550fd79f
commit 756b46ca96
26 changed files with 1684 additions and 220 deletions

View File

@ -219,6 +219,14 @@ typedef struct {
bool required; /**< Advertizes that Protected Management Frame is required. Device will not associate to non-PMF capable devices. */
} wifi_pmf_config_t;
/** Configuration for SAE PWE derivation */
typedef enum {
WPA3_SAE_PWE_UNSPECIFIED,
WPA3_SAE_PWE_HUNT_AND_PECK,
WPA3_SAE_PWE_HASH_TO_ELEMENT,
WPA3_SAE_PWE_BOTH,
} wifi_sae_pwe_method_t;
/** @brief Soft-AP configuration settings for the ESP32 */
typedef struct {
uint8_t ssid[32]; /**< SSID of ESP32 soft-AP. If ssid_len field is 0, this must be a Null terminated string. Otherwise, length is set according to ssid_len. */
@ -249,6 +257,7 @@ typedef struct {
uint32_t btm_enabled:1; /**< Whether BSS Transition Management is enabled for the connection */
uint32_t mbo_enabled:1; /**< Whether MBO is enabled for the connection */
uint32_t reserved:29; /**< Reserved for future feature set */
wifi_sae_pwe_method_t sae_pwe_h2e; /**< Whether SAE hash to element is enabled */
} wifi_sta_config_t;
/** @brief Configuration data for ESP32 AP or STA.

@ -1 +1 @@
Subproject commit ceef9ac944fd6eca042dcabf8a0e86e2c6a92ed2
Subproject commit 29ebaa55d1667097664114912a052d676477e2d4

View File

@ -54,7 +54,8 @@ set(srcs "port/os_xtensa.c"
"src/wps/wps_registrar.c"
"src/wps/wps_validate.c")
set(esp_srcs "esp_supplicant/src/esp_wpa2.c"
set(esp_srcs "esp_supplicant/src/esp_common.c"
"esp_supplicant/src/esp_wpa2.c"
"esp_supplicant/src/esp_wpa_main.c"
"esp_supplicant/src/esp_wpas_glue.c"
"esp_supplicant/src/esp_wps.c"
@ -154,7 +155,6 @@ if(CONFIG_WPA_11KV_SUPPORT)
"src/common/bss.c"
"src/common/scan.c"
"src/common/ieee802_11_common.c"
"esp_supplicant/src/esp_common.c"
"esp_supplicant/src/esp_scan.c"
)
else()

View File

@ -71,7 +71,6 @@ ifneq ($(CONFIG_WPA_11KV_SUPPORT), y)
src/common/bss.o \
src/common/scan.o \
src/common/ieee802_11_common.o \
esp_supplicant/src/esp_common.o \
esp_supplicant/src/esp_scan.o
endif
ifneq ($(CONFIG_WPA_MBO_SUPPORT), y)

View File

@ -23,6 +23,7 @@
struct wpa_supplicant g_wpa_supp;
#if defined(CONFIG_WPA_11KV_SUPPORT)
static TaskHandle_t s_supplicant_task_hdl = NULL;
static void *s_supplicant_evt_queue = NULL;
static void *s_supplicant_api_lock = NULL;
@ -229,13 +230,24 @@ static void supplicant_sta_disconn_handler(void* arg, esp_event_base_t event_bas
static int ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender,
u32 rssi, u8 channel, u64 current_tsf)
{
if (type == WLAN_FC_STYPE_BEACON || type == WLAN_FC_STYPE_PROBE_RESP) {
return esp_handle_beacon_probe(type, frame, len, sender, rssi, channel, current_tsf);
} else if (type == WLAN_FC_STYPE_ACTION) {
return handle_action_frm(frame, len, sender, rssi, channel);
int ret = 0;
switch (type) {
case WLAN_FC_STYPE_BEACON:
case WLAN_FC_STYPE_PROBE_RESP:
ret = esp_handle_beacon_probe(type, frame, len, sender, rssi, channel, current_tsf);
break;
#if defined(CONFIG_WPA_11KV_SUPPORT)
case WLAN_FC_STYPE_ACTION:
ret = handle_action_frm(frame, len, sender, rssi, channel);
break;
#endif /* defined(CONFIG_WPA_11KV_SUPPORT) */
default:
ret = -1;
break;
}
return -1;
return ret;
}
#ifdef CONFIG_MBO
@ -261,7 +273,7 @@ static bool bss_profile_match(u8 *sender)
return true;
}
#endif
#endif /* CONFIG_MBO */
int esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
{
@ -292,7 +304,6 @@ int esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
esp_scan_init(wpa_s);
wpas_rrm_reset(wpa_s);
wpas_clear_beacon_rep_data(wpa_s);
esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED,
&supplicant_sta_conn_handler, NULL);
esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED,
@ -301,6 +312,7 @@ int esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
wpa_s->type = 0;
wpa_s->subtype = 0;
esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype);
wpa_cb->wpa_sta_rx_mgmt = ieee80211_handle_rx_frm;
/* Matching is done only for MBO at the moment, this can be extended for other features*/
#ifdef CONFIG_MBO
@ -309,6 +321,7 @@ int esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
#else
wpa_cb->wpa_sta_profile_match = NULL;
#endif
return 0;
err:
esp_supplicant_common_deinit();
@ -322,6 +335,7 @@ void esp_supplicant_common_deinit(void)
esp_scan_deinit(wpa_s);
wpas_rrm_reset(wpa_s);
wpas_clear_beacon_rep_data(wpa_s);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED,
&supplicant_sta_conn_handler);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED,
@ -341,6 +355,7 @@ void esp_supplicant_common_deinit(void)
}
wpa_printf(MSG_ERROR, "failed to send task delete event");
}
}
bool esp_rrm_is_rrm_supported_connection(void)
@ -425,10 +440,6 @@ int esp_wnm_send_bss_transition_mgmt_query(enum btm_query_reason query_reason,
int esp_mbo_update_non_pref_chan(struct non_pref_chan_s *non_pref_chan)
{
int ret = wpas_mbo_update_non_pref_chan(&g_wpa_supp, non_pref_chan);
if (ret == 0) {
esp_set_assoc_ie();
}
return ret;
}
@ -470,7 +481,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));
@ -516,6 +527,7 @@ static size_t get_mbo_oce_assoc_ie(uint8_t *ie, size_t len)
return mbo_ie_len;
}
#endif
#endif
static uint8_t get_extended_caps_ie(uint8_t *ie, size_t len)
{
@ -539,7 +551,7 @@ static uint8_t get_extended_caps_ie(uint8_t *ie, size_t len)
return ext_caps_ie_len + 2;
}
#if defined(CONFIG_WPA_11KV_SUPPORT)
static uint8_t get_operating_class_ie(uint8_t *ie, size_t len)
{
uint8_t op_class_ie[4] = {0};
@ -577,20 +589,19 @@ 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
}
void esp_set_assoc_ie(void)
#endif
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);
ie = os_malloc(ASSOC_IE_LEN + ies_len);
if (!ie) {
wpa_printf(MSG_ERROR, "failed to allocate ie");
return;
@ -599,23 +610,31 @@ void esp_set_assoc_ie(void)
ie_len = get_extended_caps_ie(pos, len);
pos += ie_len;
len -= ie_len;
ie_len = get_operating_class_ie(pos, len);
pos += ie_len;
len -= ie_len;
#ifdef CONFIG_WPA_11KV_SUPPORT
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
if (ies_len) {
os_memcpy(pos, ies, ies_len);
pos += ies_len;
len -= ies_len;
}
esp_wifi_unset_appie_internal(WIFI_APPIE_ASSOC_REQ);
esp_wifi_set_appie_internal(WIFI_APPIE_ASSOC_REQ, ie, ASSOC_IE_LEN - len, 0);
os_free(ie);
#undef ASSOC_IE_LEN
}
#ifdef CONFIG_WPA_11KV_SUPPORT
void esp_get_tx_power(uint8_t *tx_power)
{
#define DEFAULT_MAX_TX_POWER 19 /* max tx power is 19.5 dbm */
@ -691,3 +710,4 @@ int esp_supplicant_post_evt(uint32_t evt_id, uint32_t data)
}
return 0;
}
#endif

View File

@ -11,7 +11,7 @@
struct wpa_funcs;
#ifdef ROAMING_SUPPORT
#ifdef CONFIG_WPA_11KV_SUPPORT
struct ieee_mgmt_frame {
u8 sender[ETH_ALEN];
u8 channel;
@ -41,7 +41,6 @@ void esp_get_tx_power(uint8_t *tx_power);
int esp_supplicant_common_init(struct wpa_funcs *wpa_cb);
void esp_supplicant_common_deinit(void);
void esp_set_scan_ie(void);
void esp_set_assoc_ie(void);
#else
#include "esp_rrm.h"
@ -49,24 +48,7 @@ void esp_set_assoc_ie(void);
#include "esp_mbo.h"
static inline void esp_set_scan_ie(void) { }
static inline void esp_set_assoc_ie(void) { }
int esp_rrm_send_neighbor_rep_request(neighbor_rep_request_cb cb,
void *cb_ctx)
{
return -1;
}
int esp_wnm_send_bss_transition_mgmt_query(enum btm_query_reason query_reason,
const char *btm_candidates,
int cand_list)
{
return -1;
}
int esp_mbo_update_non_pref_chan(struct non_pref_chan_s *non_pref_chan)
{
return -1;
}
#endif
void esp_set_assoc_ie(uint8_t *bssid, const u8 *ies, size_t ies_len, bool add_mdie);
#endif

View File

@ -105,6 +105,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 {
@ -130,6 +131,7 @@ struct wpa_funcs {
int (*wpa_sta_rx_mgmt)(u8 type, u8 *frame, size_t len, u8 *sender, u32 rssi, u8 channel, u64 current_tsf);
void (*wpa_config_done)(void);
bool (*wpa_sta_profile_match)(u8 *bssid);
int (*wpa_sta_set_ap_rsnxe)(const u8 *rsnxe, size_t rsnxe_ie_len);
};
struct wpa2_funcs {
@ -268,5 +270,8 @@ esp_err_t esp_wifi_action_tx_req(uint8_t type, uint8_t channel,
esp_err_t esp_wifi_remain_on_channel(uint8_t ifx, uint8_t type, uint8_t channel,
uint32_t wait_time_ms, wifi_action_rx_cb_t rx_cb);
bool esp_wifi_is_mbo_enabled_internal(uint8_t if_index);
uint8_t esp_wifi_sta_get_config_sae_pwe_h2e_internal(void);
uint8_t esp_wifi_sta_get_use_h2e_internal(void);
void esp_wifi_sta_disable_wpa2_authmode_internal(void);
#endif /* _ESP_WIFI_DRIVER_H_ */

View File

@ -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_sta_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;

View File

@ -116,7 +116,6 @@ bool wpa_attach(void)
ret = (esp_wifi_register_tx_cb_internal(eapol_txcb, WIFI_TXCB_EAPOL_ID) == ESP_OK);
}
esp_set_scan_ie();
esp_set_assoc_ie();
return ret;
}
@ -184,7 +183,6 @@ int wpa_sta_connect(uint8_t *bssid)
void wpa_config_done(void)
{
/* used in future for setting scan and assoc IEs */
esp_set_assoc_ie();
}
int wpa_parse_wpa_ie_wrapper(const u8 *wpa_ie, size_t wpa_ie_len, wifi_wpa_ie_t *data)
@ -200,6 +198,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;
}
@ -225,7 +224,7 @@ static void wpa_sta_disconnected_cb(uint8_t reason_code)
}
}
#ifndef ROAMING_SUPPORT
#ifndef CONFIG_WPA_11KV_SUPPORT
static inline int esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
{
wpa_cb->wpa_sta_rx_mgmt = NULL;
@ -270,6 +269,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);
ret = esp_supplicant_common_init(wpa_cb);

View File

@ -29,9 +29,6 @@
#define DEBUG_PRINT
#endif
#if CONFIG_WPA_11KV_SUPPORT
#define ROAMING_SUPPORT 1
#endif
#if CONFIG_WPA_SCAN_CACHE
#define SCAN_CACHE_SUPPORTED

View File

@ -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

View File

@ -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 */

View File

@ -149,6 +149,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_sta_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
@ -521,7 +540,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 */

View File

@ -98,6 +98,8 @@ RSN_SELECTOR(0x00, 0x0f, 0xac, 13)
#define RSN_KEY_DATA_IGTK RSN_SELECTOR(0x00, 0x0f, 0xac, 9)
#endif /* CONFIG_IEEE80211W */
#define WFA_KEY_DATA_TRANSITION_DISABLE RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x20)
#define WPA_OUI_TYPE RSN_SELECTOR(0x00, 0x50, 0xf2, 1)
#define RSN_SELECTOR_PUT(a, val) WPA_PUT_BE32((u8 *) (a), (val))
@ -318,6 +320,7 @@ struct wpa_ie_data {
size_t num_pmkid;
const u8 *pmkid;
int mgmt_group_cipher;
uint8_t rsnxe_capa;
};
struct rsn_sppamsdu_sup {
@ -353,6 +356,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,

View File

@ -653,6 +653,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
@ -729,6 +749,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()
@ -749,6 +776,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;
/**

View File

@ -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)
{

View File

@ -107,6 +107,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)
{
@ -144,6 +149,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);

View File

@ -29,6 +29,7 @@
#include "crypto/aes_wrap.h"
#include "crypto/ccmp.h"
#include "esp_rom_sys.h"
#include "esp_common_i.h"
/**
* eapol_sm_notify_eap_success - Notification of external EAP success trigger
@ -614,6 +615,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);
@ -669,16 +672,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);
}
@ -1062,6 +1079,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;
}
@ -1229,6 +1262,9 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
goto failed;
}
if (ie.transition_disable)
esp_wifi_sta_disable_wpa2_authmode_internal();
if (sm->key_install && sm->key_info & WPA_KEY_INFO_INSTALL) {
wpa_supplicant_install_ptk(sm, KEY_FLAG_RX);
}
@ -2135,6 +2171,8 @@ bool wpa_sm_init(char * payload, WPA_SEND_FUNC snd_func,
sm->wpa_deauthenticate = wpa_deauth;
sm->wpa_neg_complete = wpa_neg_complete;
sm->key_install = false;
sm->ap_rsnxe = NULL;
sm->assoc_rsnxe = NULL;
spp_attrubute = esp_wifi_get_spp_attrubute_internal(WIFI_IF_STA);
sm->spp_sup.capable = ((spp_attrubute & WPA_CAPABILITY_SPP_CAPABLE) ? SPP_AMSDU_CAP_ENABLE : SPP_AMSDU_CAP_DISABLE);
@ -2158,6 +2196,10 @@ void wpa_sm_deinit(void)
{
struct wpa_sm *sm = &gWpaSm;
pmksa_cache_deinit(sm->pmksa);
os_free(sm->ap_rsnxe);
sm->ap_rsnxe = NULL;
os_free(sm->assoc_rsnxe);
sm->assoc_rsnxe = NULL;
}
@ -2208,6 +2250,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
@ -2277,6 +2321,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;
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;
@ -2521,4 +2573,55 @@ void wpa_sta_clear_curr_pmksa(void) {
pmksa_cache_clear_current(sm);
}
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_sta_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;
}
#endif // ESP_SUPPLICANT

View File

@ -136,4 +136,12 @@ unsigned cipher_type_map_public_to_supp(wifi_cipher_type_t cipher);
void wpa_sta_clear_curr_pmksa(void);
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);
struct wpa_sm * get_wpa_sm(void);
void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm);
#endif /* WPA_H */

View File

@ -52,12 +52,15 @@ 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*/
ETSTimer cm_timer;
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;
@ -69,8 +72,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;

View File

@ -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;
}
@ -289,6 +291,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
@ -349,6 +379,15 @@ static int wpa_parse_generic(const u8 *pos, const u8 *end,
return 0;
}
#endif
if (pos[1] >= RSN_SELECTOR_LEN + 1 &&
RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_TRANSITION_DISABLE) {
ie->transition_disable = pos + 2 + RSN_SELECTOR_LEN;
ie->transition_disable_len = pos[1] - RSN_SELECTOR_LEN;
wpa_hexdump(MSG_DEBUG,
"WPA: Transition Disable KDE in EAPOL-Key",
pos, pos[1] + 2);
return 0;
}
return 0;
}
@ -389,6 +428,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)

View File

@ -37,12 +37,16 @@ struct wpa_eapol_ie_parse {
const u8 *reassoc_deadline;
const u8 *key_lifetime;
#endif /* CONFIG_IEEE80211R */
const u8 *transition_disable;
size_t transition_disable_len;
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);

View 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 */

View File

@ -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);

View File

@ -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 = WPA3_SAE_PWE_BOTH,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
@ -142,6 +143,11 @@ void wifi_init_sta(void)
} else {
ESP_LOGE(TAG, "UNEXPECTED EVENT");
}
/* The event will not be processed after unregister */
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
vEventGroupDelete(s_wifi_event_group);
}
void app_main(void)