mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-06-27 20:27:43 +08:00
feat(wpa_supplicant): refactor wpa_supplicant
This commit is contained in:
@ -15,6 +15,10 @@
|
||||
#ifndef _ESP_WIFI_INTERNAL_H
|
||||
#define _ESP_WIFI_INTERNAL_H
|
||||
|
||||
#include "esp_wifi_types.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_wifi.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -58,6 +62,44 @@ typedef enum {
|
||||
#define WIFI_LOG_SUBMODULE_FRAG (1<<14)
|
||||
#define WIFI_LOG_SUBMODULE_WPA2 (1<<15)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize Wi-Fi Driver
|
||||
* Alloc resource for WiFi driver, such as WiFi control structure, RX/TX buffer,
|
||||
* WiFi NVS structure among others.
|
||||
*
|
||||
* For the most part, you need not call this function directly. It gets called
|
||||
* from esp_wifi_init().
|
||||
*
|
||||
* This function may be called, if you only need to initialize the Wi-Fi driver
|
||||
* without having to use the network stack on top.
|
||||
*
|
||||
* @param config provide WiFi init configuration
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - ESP_ERR_NO_MEM: out of memory
|
||||
* - others: refer to error code esp_err.h
|
||||
*/
|
||||
esp_err_t esp_wifi_init_internal(const wifi_init_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize Wi-Fi Driver
|
||||
* Free resource for WiFi driver, such as WiFi control structure, RX/TX buffer,
|
||||
* WiFi NVS structure among others.
|
||||
*
|
||||
* For the most part, you need not call this function directly. It gets called
|
||||
* from esp_wifi_deinit().
|
||||
*
|
||||
* This function may be called, if you call esp_wifi_init_internal to initialize
|
||||
* WiFi driver.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: refer to error code esp_err.h
|
||||
*/
|
||||
esp_err_t esp_wifi_deinit_internal(void);
|
||||
|
||||
/**
|
||||
* @brief Set WIFI received TCP/IP data cache ram type
|
||||
*
|
||||
|
@ -89,12 +89,16 @@ typedef enum {
|
||||
WIFI_REASON_802_1X_AUTH_FAILED = 23,
|
||||
WIFI_REASON_CIPHER_SUITE_REJECTED = 24,
|
||||
|
||||
WIFI_REASON_INVALID_PMKID = 53,
|
||||
|
||||
WIFI_REASON_BEACON_TIMEOUT = 200,
|
||||
WIFI_REASON_NO_AP_FOUND = 201,
|
||||
WIFI_REASON_AUTH_FAIL = 202,
|
||||
WIFI_REASON_ASSOC_FAIL = 203,
|
||||
WIFI_REASON_HANDSHAKE_TIMEOUT = 204,
|
||||
WIFI_REASON_BASIC_RATE_NOT_SUPPORT = 205,
|
||||
WIFI_REASON_CONNECTION_FAIL = 205,
|
||||
WIFI_REASON_AP_TSF_RESET = 206,
|
||||
WIFI_REASON_BASIC_RATE_NOT_SUPPORT = 207,
|
||||
} wifi_err_reason_t;
|
||||
|
||||
typedef enum {
|
||||
@ -517,6 +521,10 @@ typedef struct {
|
||||
wifi_auth_mode_t new_mode; /**< the new auth mode of AP */
|
||||
} wifi_event_sta_authmode_change_t;
|
||||
|
||||
#define MAX_SSID_LEN 32
|
||||
#define MAX_PASSPHRASE_LEN 64
|
||||
#define MAX_WPS_AP_CRED 3
|
||||
|
||||
/** Argument structure for WIFI_EVENT_STA_WPS_ER_PIN event */
|
||||
typedef struct {
|
||||
uint8_t pin_code[8]; /**< PIN code of station in enrollee mode */
|
||||
|
@ -60,6 +60,16 @@ void vPortETSIntrUnlock(void);
|
||||
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
|
||||
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
|
||||
typedef uint32_t ETSSignal;
|
||||
typedef uint32_t ETSParam;
|
||||
|
||||
typedef struct ETSEventTag ETSEvent; /**< Event transmit/receive in ets*/
|
||||
|
||||
struct ETSEventTag {
|
||||
ETSSignal sig; /**< Event signal, in same task, different Event with different signal*/
|
||||
ETSParam par; /**< Event parameter, sometimes without usage, then will be set as 0*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Delay function, maximum value: 65535 us.
|
||||
*
|
||||
|
@ -12,6 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_libc.h"
|
||||
#include "esp_system.h"
|
||||
@ -19,6 +21,8 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_private/wifi.h"
|
||||
#include "phy.h"
|
||||
#include "esp_supplicant/esp_wpa.h"
|
||||
#include "esp_aio.h"
|
||||
|
||||
#define TAG "wifi_init"
|
||||
|
||||
@ -30,8 +34,10 @@ const bool _g_esp_wifi_connect_open_router_when_pwd_is_set = true;
|
||||
const bool _g_esp_wifi_connect_open_router_when_pwd_is_set = false;
|
||||
#endif
|
||||
|
||||
#define EP_OFFSET 36
|
||||
int ieee80211_output_pbuf(esp_aio_t *aio);
|
||||
|
||||
esp_err_t mac_init(void);
|
||||
esp_err_t esp_wifi_init_internal(const wifi_init_config_t *config);
|
||||
|
||||
ESP_EVENT_DEFINE_BASE(WIFI_EVENT);
|
||||
|
||||
@ -109,6 +115,19 @@ static void esp_wifi_set_debug_log()
|
||||
#endif /* CONFIG_ESP8266_WIFI_DEBUG_LOG_ENABLE*/
|
||||
}
|
||||
|
||||
esp_err_t esp_wifi_deinit(void)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
esp_supplicant_deinit();
|
||||
err = esp_wifi_deinit_internal();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to deinit Wi-Fi driver (0x%x)", err);
|
||||
return err;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Init WiFi
|
||||
* Alloc resource for WiFi driver, such as WiFi control structure, RX/TX buffer,
|
||||
@ -137,6 +156,16 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config)
|
||||
esp_err_t result = esp_wifi_init_internal(config);
|
||||
if (result == ESP_OK) {
|
||||
esp_wifi_set_debug_log();
|
||||
result = esp_supplicant_init();
|
||||
if (result != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to init supplicant (0x%x)", result);
|
||||
esp_err_t deinit_ret = esp_wifi_deinit();
|
||||
if (deinit_ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to deinit Wi-Fi (0x%x)", deinit_ret);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result = tcpip_adapter_set_default_wifi_handlers();
|
||||
@ -169,3 +198,42 @@ bool IRAM_ATTR esp_wifi_try_rate_from_high(void) {
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
int wifi_internal_send_cb(esp_aio_t* aio)
|
||||
{
|
||||
char* pb = (char*)aio->arg;
|
||||
|
||||
if (pb) {
|
||||
os_free(pb);
|
||||
pb = NULL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int esp_wifi_internal_tx(wifi_interface_t wifi_if, void *buffer, uint16_t len)
|
||||
{
|
||||
esp_aio_t aio;
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint8_t *dram_buffer = (uint8_t *)heap_caps_malloc(len + EP_OFFSET, MALLOC_CAP_8BIT);
|
||||
if (!dram_buffer) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
dram_buffer = ((uint8_t *)dram_buffer + EP_OFFSET);
|
||||
memcpy(dram_buffer, buffer, len);
|
||||
|
||||
aio.arg = (char *)dram_buffer - EP_OFFSET;
|
||||
aio.cb = wifi_internal_send_cb;
|
||||
aio.fd = wifi_if;
|
||||
aio.pbuf = (char *)dram_buffer;
|
||||
aio.len = len;
|
||||
aio.ret = 0;
|
||||
ret = ieee80211_output_pbuf(&aio);
|
||||
|
||||
if(ret != 0) {
|
||||
os_free(aio.arg);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -56,19 +56,12 @@ set(srcs "port/os_xtensa.c"
|
||||
"src/eap_peer/eap_tls_common.c"
|
||||
"src/eap_peer/eap_ttls.c"
|
||||
"src/eap_peer/mschapv2.c"
|
||||
"src/esp_supplicant/esp_hostap.c"
|
||||
"src/esp_supplicant/esp_wpa2.c"
|
||||
"src/esp_supplicant/esp_wpa_main.c"
|
||||
"src/esp_supplicant/esp_wpas_glue.c"
|
||||
"src/esp_supplicant/esp_wps.c"
|
||||
"src/esp_supplicant/esp_wpa3.c"
|
||||
"src/fast_crypto/fast_aes-cbc.c"
|
||||
"src/fast_crypto/fast_aes-unwrap.c"
|
||||
"src/fast_crypto/fast_aes-wrap.c"
|
||||
"src/fast_crypto/fast_crypto_internal.c"
|
||||
"src/fast_crypto/fast_crypto_internal-cipher.c"
|
||||
"src/fast_crypto/fast_crypto_internal-modexp.c"
|
||||
"src/fast_crypto/fast_crypto_ops.c"
|
||||
"src/fast_crypto/fast_sha256.c"
|
||||
"src/fast_crypto/fast_sha256-internal.c"
|
||||
"src/rsn_supp/pmksa_cache.c"
|
||||
"src/rsn_supp/wpa.c"
|
||||
"src/rsn_supp/wpa_ie.c"
|
||||
|
@ -1,7 +1,7 @@
|
||||
# supplicant make file
|
||||
|
||||
COMPONENT_PRIV_INCLUDEDIRS := src
|
||||
COMPONENT_SRCDIRS := port src/ap src/common src/crypto src/eap_peer src/fast_crypto src/rsn_supp src/tls src/utils src/esp_supplicant src/wps
|
||||
COMPONENT_SRCDIRS := port src/ap src/common src/crypto src/eap_peer src/rsn_supp src/tls src/utils src/esp_supplicant src/wps
|
||||
COMPONENT_ADD_INCLUDEDIRS := include port/include include/esp_supplicant
|
||||
|
||||
ifeq ($(CONFIG_WPA_MBEDTLS_CRYPTO), y)
|
||||
|
14
components/wpa_supplicant/include/esp_supplicant/esp_wpa2.h
Normal file → Executable file
14
components/wpa_supplicant/include/esp_supplicant/esp_wpa2.h
Normal file → Executable file
@ -16,23 +16,13 @@
|
||||
#define _ESP_WPA2_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp_wifi_crypto_types.h"
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const wpa2_crypto_funcs_t g_wifi_default_wpa2_crypto_funcs;
|
||||
|
||||
typedef struct {
|
||||
const wpa2_crypto_funcs_t *crypto_funcs;
|
||||
}esp_wpa2_config_t;
|
||||
|
||||
#define WPA2_CONFIG_INIT_DEFAULT() { \
|
||||
.crypto_funcs = &g_wifi_default_wpa2_crypto_funcs \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable wpa2 enterprise authentication.
|
||||
*
|
||||
@ -43,7 +33,7 @@ typedef struct {
|
||||
* - ESP_OK: succeed.
|
||||
* - ESP_ERR_NO_MEM: fail(internal memory malloc fail)
|
||||
*/
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_enable(const esp_wpa2_config_t *config);
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_enable(void);
|
||||
|
||||
/**
|
||||
* @brief Disable wpa2 enterprise authentication.
|
||||
|
@ -55,8 +55,6 @@ typedef enum wps_type {
|
||||
WPS_TYPE_MAX,
|
||||
} wps_type_t;
|
||||
|
||||
extern const wps_crypto_funcs_t g_wifi_default_wps_crypto_funcs;
|
||||
|
||||
#define WPS_MAX_MANUFACTURER_LEN 65
|
||||
#define WPS_MAX_MODEL_NUMBER_LEN 33
|
||||
#define WPS_MAX_MODEL_NAME_LEN 33
|
||||
@ -71,13 +69,11 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
wps_type_t wps_type;
|
||||
const wps_crypto_funcs_t *crypto_funcs;
|
||||
wps_factory_information_t factory_info;
|
||||
} esp_wps_config_t;
|
||||
|
||||
#define WPS_CONFIG_INIT_DEFAULT(type) { \
|
||||
.wps_type = type, \
|
||||
.crypto_funcs = &g_wifi_default_wps_crypto_funcs, \
|
||||
.factory_info = { \
|
||||
ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(manufacturer, "ESPRESSIF") \
|
||||
ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(model_number, "ESP8266") \
|
||||
|
@ -27,9 +27,7 @@
|
||||
|
||||
#include "esp_supplicant/esp_wifi_driver.h"
|
||||
#include "esp_wifi.h"
|
||||
|
||||
#define wpa_malloc_dram(s) heap_caps_malloc(s, MALLOC_CAP_8BIT)
|
||||
#define wpa_calloc_dram(n, s) heap_caps_calloc(n, s, MALLOC_CAP_8BIT)
|
||||
#include "esp_private/wifi.h"
|
||||
|
||||
#define STATE_MACHINE_DATA struct wpa_state_machine
|
||||
#define STATE_MACHINE_DEBUG_PREFIX "WPA"
|
||||
@ -57,8 +55,6 @@ static const u32 eapol_key_timeout_first_group = 500; /* ms */
|
||||
static void *s_sm_table[WPA_SM_MAX_INDEX];
|
||||
static u32 s_sm_valid_bitmap = 0;
|
||||
|
||||
ETSTimer resend_eapol;
|
||||
|
||||
static struct wpa_state_machine * wpa_auth_get_sm(u32 index)
|
||||
{
|
||||
if ( (index < WPA_SM_MAX_INDEX) && (BIT(index) & s_sm_valid_bitmap)){
|
||||
@ -153,79 +149,28 @@ static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth,
|
||||
return -1;
|
||||
}
|
||||
|
||||
#include "esp_aio.h"
|
||||
int ieee80211_output_pbuf(esp_aio_t *aio);
|
||||
#define EP_OFFSET 36
|
||||
/* fix buf for tx for now */
|
||||
#define WPA_TX_MSG_BUFF_MAXLEN 200
|
||||
|
||||
static int wpa_auth_send_cb(esp_aio_t* aio)
|
||||
{
|
||||
char* pb = (char*)aio->arg;
|
||||
|
||||
os_free(pb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
wpa_auth_send_eapol(struct wpa_authenticator *wpa_auth, const u8 *addr,
|
||||
const u8 *data, size_t data_len, int encrypt)
|
||||
{
|
||||
// wujg : need to add send data function
|
||||
void *buffer = os_malloc(256);
|
||||
struct l2_ethhdr *eth = buffer;
|
||||
|
||||
#ifndef IOT_SIP_MODE
|
||||
esp_aio_t aio;
|
||||
uint8_t* pb = wpa_malloc_dram(data_len + EP_OFFSET + sizeof(struct l2_ethhdr));
|
||||
struct l2_ethhdr* eth;
|
||||
u8 mac[6];
|
||||
pb = pb + EP_OFFSET;
|
||||
esp_wifi_get_mac(WIFI_IF_AP, mac);
|
||||
|
||||
if (pb == NULL) {
|
||||
wpa_printf( MSG_DEBUG, "send_eapol, buffer=%p\n", pb);
|
||||
if (!buffer){
|
||||
wpa_printf( MSG_DEBUG, "send_eapol, buffer=%p\n", buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
eth = (struct l2_ethhdr*)pb;
|
||||
os_memcpy(eth->h_dest, addr, ETH_ALEN);
|
||||
os_memcpy(eth->h_source, mac, ETH_ALEN);
|
||||
memcpy(eth->h_dest, addr, ETH_ALEN);
|
||||
memcpy(eth->h_source, wpa_auth->addr, ETH_ALEN);
|
||||
eth->h_proto = host_to_be16(ETH_P_EAPOL);
|
||||
|
||||
os_memcpy((uint8_t*)pb + sizeof(struct l2_ethhdr), data, data_len);
|
||||
|
||||
aio.arg = pb - EP_OFFSET;
|
||||
aio.cb = wpa_auth_send_cb;
|
||||
aio.fd = 1;
|
||||
aio.pbuf = (char *)pb;
|
||||
aio.len = sizeof(struct l2_ethhdr) + data_len;
|
||||
aio.ret = 0;
|
||||
|
||||
if (ieee80211_output_pbuf(&aio) != 0) {
|
||||
os_free(pb - EP_OFFSET);
|
||||
wpa_printf(MSG_INFO, "wpa_auth_send_eapol failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
esf_buf* eb = NULL;
|
||||
struct l2_ethhdr* eth;
|
||||
uint8_t* frm;
|
||||
|
||||
eb = ieee80211_getmgtframe(&frm, sizeof(struct ieee80211_frame), WPA_TX_MSG_BUFF_MAXLEN);
|
||||
eth = etod(eb, struct l2_ethhdr);
|
||||
os_memcpy(eth->h_dest, addr, ETH_ALEN);
|
||||
os_memcpy(eth->h_source, g_ic.ic_if1_conn->ni_myaddr, ETH_ALEN);
|
||||
eth->h_proto = host_to_be16(ETH_P_EAPOL);
|
||||
|
||||
os_memcpy(frm + sizeof(struct l2_ethhdr), data, data_len);
|
||||
|
||||
eb->hdr_len = sizeof(struct ieee80211_frame);
|
||||
eb->data_len = sizeof(struct l2_ethhdr) + data_len;
|
||||
|
||||
ieee80211_output_pbuf(g_ic.ic_if1_conn, eb);
|
||||
#endif
|
||||
|
||||
memcpy((char *)buffer + sizeof(struct l2_ethhdr), data, data_len);
|
||||
esp_wifi_internal_tx(1, buffer, sizeof(struct l2_ethhdr) + data_len);
|
||||
os_free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -239,9 +184,8 @@ int wpa_auth_for_each_sta(struct wpa_authenticator *wpa_auth,
|
||||
static void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth,
|
||||
const u8 *addr)
|
||||
{
|
||||
// wujg : need to add disconnect function
|
||||
wpa_printf(MSG_DEBUG, "wpa_sta_disconnect STA " MACSTR, MAC2STR(addr));
|
||||
//esp_wifi_ap_deauth_internal((uint8_t*)addr, WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT);
|
||||
esp_wifi_ap_deauth_internal((uint8_t*)addr, WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -490,8 +434,8 @@ void wpa_auth_sta_deinit(struct wpa_state_machine *sm)
|
||||
if (sm == NULL)
|
||||
return;
|
||||
|
||||
ets_timer_disarm(&resend_eapol);
|
||||
ets_timer_done(&resend_eapol);
|
||||
ets_timer_disarm(&sm->resend_eapol);
|
||||
ets_timer_done(&sm->resend_eapol);
|
||||
|
||||
if (sm->in_step_loop) {
|
||||
/* Must not free state machine while wpa_sm_step() is running.
|
||||
@ -870,8 +814,8 @@ continue_processing:
|
||||
}
|
||||
sm->MICVerified = TRUE;
|
||||
eloop_cancel_timeout(wpa_send_eapol_timeout, wpa_auth, sm);
|
||||
ets_timer_disarm(&resend_eapol);
|
||||
ets_timer_done(&resend_eapol);
|
||||
ets_timer_disarm(&sm->resend_eapol);
|
||||
ets_timer_done(&sm->resend_eapol);
|
||||
sm->pending_1_of_4_timeout = 0;
|
||||
}
|
||||
|
||||
@ -1155,7 +1099,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
|
||||
os_free(hdr);
|
||||
}
|
||||
|
||||
void resend_eapol_handle(void *timeout_ctx)
|
||||
int hostap_eapol_resend_process(void *timeout_ctx)
|
||||
{
|
||||
u32 index = (u32)timeout_ctx;
|
||||
struct wpa_state_machine *sm = wpa_auth_get_sm(index);
|
||||
@ -1170,6 +1114,18 @@ void resend_eapol_handle(void *timeout_ctx)
|
||||
} else {
|
||||
wpa_printf( MSG_INFO, "Station left, stop send EAPOL frame");
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void resend_eapol_handle(void *timeout_ctx)
|
||||
{
|
||||
wifi_ipc_config_t cfg;
|
||||
|
||||
cfg.fn = hostap_eapol_resend_process;
|
||||
cfg.arg = timeout_ctx;
|
||||
cfg.arg_size = 0;
|
||||
esp_wifi_ipc_internal(&cfg, false);
|
||||
}
|
||||
|
||||
static void wpa_send_eapol(struct wpa_authenticator *wpa_auth,
|
||||
@ -1200,9 +1156,9 @@ static void wpa_send_eapol(struct wpa_authenticator *wpa_auth,
|
||||
"counter %d)\n", timeout_ms, ctr);
|
||||
eloop_register_timeout(timeout_ms / 1000, (timeout_ms % 1000) * 1000,
|
||||
wpa_send_eapol_timeout, wpa_auth, sm);
|
||||
ets_timer_disarm(&resend_eapol);
|
||||
ets_timer_setfn(&resend_eapol, (ETSTimerFunc *)resend_eapol_handle, (void*)(sm->index));
|
||||
ets_timer_arm(&resend_eapol, 1000, 0);
|
||||
ets_timer_disarm(&sm->resend_eapol);
|
||||
ets_timer_setfn(&sm->resend_eapol, (ETSTimerFunc *)resend_eapol_handle, (void*)(sm->index));
|
||||
ets_timer_arm(&sm->resend_eapol, 1000, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -117,6 +117,7 @@ struct wpa_state_machine {
|
||||
|
||||
int pending_1_of_4_timeout;
|
||||
u32 index;
|
||||
ETSTimer resend_eapol;
|
||||
};
|
||||
|
||||
|
||||
|
@ -384,7 +384,7 @@ static void tls_set_ciphersuite(tls_context_t *tls)
|
||||
if (tls->ciphersuite[0]) {
|
||||
mbedtls_ssl_conf_ciphersuites(&tls->conf, tls->ciphersuite);
|
||||
} else if (mbedtls_pk_get_bitlen(&tls->clientkey) > 2048 ||
|
||||
mbedtls_pk_get_bitlen(&tls->cacert_ptr->pk) > 2048) {
|
||||
(tls->cacert_ptr && mbedtls_pk_get_bitlen(&tls->cacert_ptr->pk) > 2048)) {
|
||||
mbedtls_ssl_conf_ciphersuites(&tls->conf, eap_ciphersuite_preference);
|
||||
}
|
||||
}
|
||||
@ -504,6 +504,7 @@ void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
|
||||
{
|
||||
/* Free ssl ctx and data */
|
||||
tls_mbedtls_conn_delete((tls_context_t *) conn->tls);
|
||||
os_free(conn->tls);
|
||||
conn->tls = NULL;
|
||||
/* Data in in ssl ctx, free connection */
|
||||
os_free(conn);
|
||||
|
@ -98,6 +98,13 @@ struct eap_method {
|
||||
#define BLOB_NAME_LEN 3
|
||||
#define BLOB_NUM 3
|
||||
|
||||
enum SIG_WPA2 {
|
||||
SIG_WPA2_START = 0,
|
||||
SIG_WPA2_RX,
|
||||
SIG_WPA2_TASK_DEL,
|
||||
SIG_WPA2_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct eap_sm - EAP state machine data
|
||||
*/
|
||||
@ -114,8 +121,7 @@ struct eap_sm {
|
||||
u8 current_identifier;
|
||||
u8 ownaddr[ETH_ALEN];
|
||||
#ifdef USE_WPA2_TASK
|
||||
#define SIG_WPA2_NUM 2
|
||||
u8 wpa2_sig_cnt[SIG_WPA2_NUM];
|
||||
u8 wpa2_sig_cnt[SIG_WPA2_MAX];
|
||||
#endif
|
||||
u8 finish_state;
|
||||
|
||||
|
136
components/wpa_supplicant/src/esp_supplicant/esp_hostap.c
Executable file
136
components/wpa_supplicant/src/esp_supplicant/esp_hostap.c
Executable file
@ -0,0 +1,136 @@
|
||||
// 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.
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "crypto/sha1.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/eapol_common.h"
|
||||
#include "ap/wpa_auth.h"
|
||||
#include "ap/ap_config.h"
|
||||
#include "utils/wpa_debug.h"
|
||||
#include "ap/hostapd.h"
|
||||
#include "ap/wpa_auth_i.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
#include "esp_wifi_types.h"
|
||||
|
||||
void *hostap_init(void)
|
||||
{
|
||||
struct wifi_ssid *ssid = esp_wifi_ap_get_prof_ap_ssid_internal();
|
||||
struct hostapd_data *hapd = NULL;
|
||||
struct wpa_auth_config *auth_conf;
|
||||
u8 mac[6];
|
||||
|
||||
hapd = (struct hostapd_data *)os_zalloc(sizeof(struct hostapd_data));
|
||||
|
||||
if (hapd == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hapd->conf = (struct hostapd_bss_config *)os_zalloc(sizeof(struct hostapd_bss_config));
|
||||
|
||||
if (hapd->conf == NULL) {
|
||||
os_free(hapd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
auth_conf = (struct wpa_auth_config *)os_zalloc(sizeof(struct wpa_auth_config));
|
||||
|
||||
if (auth_conf == NULL) {
|
||||
os_free(hapd->conf);
|
||||
os_free(hapd);
|
||||
hapd = NULL;
|
||||
return NULL;
|
||||
}
|
||||
if (esp_wifi_ap_get_prof_authmode_internal() == WIFI_AUTH_WPA_PSK) {
|
||||
auth_conf->wpa = WPA_PROTO_WPA;
|
||||
}
|
||||
if (esp_wifi_ap_get_prof_authmode_internal() == WIFI_AUTH_WPA2_PSK) {
|
||||
auth_conf->wpa = WPA_PROTO_RSN;
|
||||
}
|
||||
if (esp_wifi_ap_get_prof_authmode_internal() == WIFI_AUTH_WPA_WPA2_PSK) {
|
||||
auth_conf->wpa = WPA_PROTO_RSN | WPA_PROTO_WPA;
|
||||
}
|
||||
|
||||
auth_conf->wpa_group = WPA_CIPHER_TKIP;
|
||||
auth_conf->wpa_pairwise = WPA_CIPHER_CCMP | WPA_CIPHER_TKIP;
|
||||
auth_conf->rsn_pairwise = WPA_CIPHER_CCMP | WPA_CIPHER_TKIP;
|
||||
auth_conf->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
|
||||
auth_conf->eapol_version = EAPOL_VERSION;
|
||||
|
||||
memcpy(hapd->conf->ssid.ssid, ssid->ssid, ssid->len);
|
||||
hapd->conf->ssid.ssid_len = ssid->len;
|
||||
hapd->conf->ssid.wpa_passphrase = (char *)os_zalloc(64);
|
||||
if (hapd->conf->ssid.wpa_passphrase == NULL) {
|
||||
os_free(auth_conf);
|
||||
os_free(hapd->conf);
|
||||
os_free(hapd);
|
||||
hapd = NULL;
|
||||
return NULL;
|
||||
}
|
||||
memcpy(hapd->conf->ssid.wpa_passphrase, esp_wifi_ap_get_prof_password_internal(), strlen((char *)esp_wifi_ap_get_prof_password_internal()));
|
||||
|
||||
hapd->conf->ap_max_inactivity = 5 * 60;
|
||||
hostapd_setup_wpa_psk(hapd->conf);
|
||||
|
||||
esp_wifi_get_macaddr_internal(WIFI_IF_AP, mac);
|
||||
|
||||
hapd->wpa_auth = wpa_init(mac, auth_conf, NULL);
|
||||
esp_wifi_set_appie_internal(WIFI_APPIE_WPA, hapd->wpa_auth->wpa_ie, (uint16_t)hapd->wpa_auth->wpa_ie_len, 0);
|
||||
os_free(auth_conf);
|
||||
|
||||
return (void *)hapd;
|
||||
}
|
||||
|
||||
bool hostap_deinit(void *data)
|
||||
{
|
||||
struct hostapd_data *hapd = (struct hostapd_data *)data;
|
||||
|
||||
if (hapd == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hapd->wpa_auth->wpa_ie != NULL) {
|
||||
os_free(hapd->wpa_auth->wpa_ie);
|
||||
}
|
||||
|
||||
if (hapd->wpa_auth->group != NULL) {
|
||||
os_free(hapd->wpa_auth->group);
|
||||
}
|
||||
|
||||
if (hapd->wpa_auth != NULL) {
|
||||
os_free(hapd->wpa_auth);
|
||||
}
|
||||
|
||||
if (hapd->conf->ssid.wpa_psk != NULL) {
|
||||
os_free(hapd->conf->ssid.wpa_psk);
|
||||
}
|
||||
|
||||
if (hapd->conf->ssid.wpa_passphrase != NULL) {
|
||||
os_free(hapd->conf->ssid.wpa_passphrase);
|
||||
}
|
||||
|
||||
if (hapd->conf != NULL) {
|
||||
os_free(hapd->conf);
|
||||
}
|
||||
|
||||
if (hapd != NULL) {
|
||||
os_free(hapd);
|
||||
}
|
||||
|
||||
esp_wifi_unset_appie_internal(WIFI_APPIE_WPA);
|
||||
|
||||
return true;
|
||||
}
|
@ -18,6 +18,30 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_wifi.h"
|
||||
|
||||
#if CONFIG_NEWLIB_NANO_FORMAT
|
||||
#define TASK_STACK_SIZE_ADD 0
|
||||
#else
|
||||
#define TASK_STACK_SIZE_ADD 512
|
||||
#endif
|
||||
|
||||
#define WPA2_TASK_STACK_SIZE (6144 + TASK_STACK_SIZE_ADD)
|
||||
#define WPS_TASK_STACK_SIZE (12288 + TASK_STACK_SIZE_ADD)
|
||||
|
||||
enum {
|
||||
WIFI_APPIE_PROBEREQ = 0,
|
||||
WIFI_APPIE_ASSOC_REQ,
|
||||
WIFI_APPIE_ASSOC_RESP,
|
||||
WIFI_APPIE_WPA,
|
||||
WIFI_APPIE_RSN,
|
||||
WIFI_APPIE_WPS_PR,
|
||||
WIFI_APPIE_WPS_AR,
|
||||
WIFI_APPIE_MESH_QUICK,
|
||||
WIFI_APPIE_FREQ_ERROR,
|
||||
WIFI_APPIE_ESP_MANUFACTOR,
|
||||
WIFI_APPIE_COUNTRY,
|
||||
WIFI_APPIE_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
NONE_AUTH = 0x01,
|
||||
WPA_AUTH_UNSPEC = 0x02,
|
||||
@ -31,11 +55,100 @@ enum {
|
||||
WPA2_AUTH_INVALID = 0x0a,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
WPA2_ENT_EAP_STATE_NOT_START,
|
||||
WPA2_ENT_EAP_STATE_IN_PROGRESS,
|
||||
WPA2_ENT_EAP_STATE_SUCCESS,
|
||||
WPA2_ENT_EAP_STATE_FAIL,
|
||||
} wpa2_ent_eap_state_t;
|
||||
|
||||
struct wifi_ssid {
|
||||
int len;
|
||||
uint8_t ssid[32];
|
||||
};
|
||||
|
||||
struct wps_scan_ie {
|
||||
uint8_t *bssid;
|
||||
uint8_t chan;
|
||||
uint16_t capinfo;
|
||||
uint8_t *ssid;
|
||||
uint8_t *wpa;
|
||||
uint8_t *rsn;
|
||||
uint8_t *wps;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int proto;
|
||||
int pairwise_cipher;
|
||||
int group_cipher;
|
||||
int key_mgmt;
|
||||
int capabilities;
|
||||
size_t num_pmkid;
|
||||
const u8 *pmkid;
|
||||
int mgmt_group_cipher;
|
||||
} wifi_wpa_ie_t;
|
||||
|
||||
struct wpa_funcs {
|
||||
bool (*wpa_sta_init)(void);
|
||||
bool (*wpa_sta_deinit)(void);
|
||||
void (*wpa_sta_connect)(uint8_t *bssid);
|
||||
void (*wpa_sta_disconnected_cb)(uint8_t reason_code);
|
||||
int (*wpa_sta_rx_eapol)(u8 *src_addr, u8 *buf, u32 len);
|
||||
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);
|
||||
bool (*wpa_ap_remove)(void *sm);
|
||||
uint8_t *(*wpa_ap_get_wpa_ie)(uint8_t *len);
|
||||
bool (*wpa_ap_rx_eapol)(void *hapd_data, void *sm, u8 *data, size_t data_len);
|
||||
char *(*wpa_config_parse_string)(const char *value, size_t *len);
|
||||
int (*wpa_parse_wpa_ie)(const u8 *wpa_ie, size_t wpa_ie_len, wifi_wpa_ie_t *data);
|
||||
int (*wpa_config_bss)(u8 *bssid);
|
||||
int (*wpa_michael_mic_failure)(u16 is_unicast);
|
||||
uint8_t *(*wpa3_build_sae_msg)(uint8_t *bssid, uint32_t type, size_t *len);
|
||||
int (*wpa3_parse_sae_msg)(uint8_t *buf, size_t len, uint32_t type, uint16_t status);
|
||||
};
|
||||
|
||||
struct wpa2_funcs {
|
||||
int (*wpa2_sm_rx_eapol)(u8 *src_addr, u8 *buf, u32 len, u8 *bssid);
|
||||
int (*wpa2_start)(void);
|
||||
int (*wpa2_init)(void);
|
||||
void (*wpa2_deinit)(void);
|
||||
};
|
||||
|
||||
struct wps_funcs {
|
||||
bool (*wps_parse_scan_result)(struct wps_scan_ie *scan);
|
||||
int (*wifi_station_wps_start)(void);
|
||||
int (*wps_sm_rx_eapol)(u8 *src_addr, u8 *buf, u32 len);
|
||||
int (*wps_start_pending)(void);
|
||||
};
|
||||
|
||||
typedef esp_err_t (*wifi_wpa2_fn_t)(void *);
|
||||
typedef struct {
|
||||
wifi_wpa2_fn_t fn;
|
||||
void *param;
|
||||
} wifi_wpa2_param_t;
|
||||
|
||||
#define IS_WPS_REGISTRAR(type) (((type)>WPS_TYPE_MAX)?(((type)<WPS_TYPE_MAX)?true:false):false)
|
||||
#define IS_WPS_ENROLLEE(type) (((type)>WPS_TYPE_DISABLE)?(((type)<WPS_TYPE_MAX)?true:false):false)
|
||||
|
||||
typedef enum wps_status {
|
||||
WPS_STATUS_DISABLE = 0,
|
||||
WPS_STATUS_SCANNING,
|
||||
WPS_STATUS_PENDING,
|
||||
WPS_STATUS_SUCCESS,
|
||||
WPS_STATUS_MAX,
|
||||
} WPS_STATUS_t;
|
||||
|
||||
#define WIFI_TXCB_EAPOL_ID 3
|
||||
typedef void(*wifi_tx_cb_t)(void *);
|
||||
typedef int (*wifi_ipc_fn_t)(void *);
|
||||
typedef struct {
|
||||
wifi_ipc_fn_t fn;
|
||||
void *arg;
|
||||
uint32_t arg_size;
|
||||
} wifi_ipc_config_t;
|
||||
|
||||
#define WPA_IGTK_LEN 16
|
||||
typedef struct {
|
||||
uint8_t keyid[2];
|
||||
@ -45,6 +158,10 @@ typedef struct {
|
||||
|
||||
/*wpa_auth.c*/
|
||||
uint8_t *esp_wifi_ap_get_prof_pmk_internal(void);
|
||||
struct wifi_ssid *esp_wifi_ap_get_prof_ap_ssid_internal(void);
|
||||
uint8_t esp_wifi_ap_get_prof_authmode_internal(void);
|
||||
//uint8_t esp_wifi_sta_get_prof_authmode_internal(void);
|
||||
uint8_t *esp_wifi_ap_get_prof_password_internal(void);
|
||||
void *esp_wifi_get_hostap_private_internal(void);
|
||||
int esp_wifi_set_ap_key_internal(int alg, const u8 *addr, int idx, u8 *key, size_t key_len);
|
||||
bool esp_wifi_wpa_ptk_init_done_internal(uint8_t *mac);
|
||||
@ -76,9 +193,36 @@ void esp_wifi_deauthenticate_internal(u8 reason_code);
|
||||
uint8_t esp_wifi_sta_get_pairwise_cipher_internal(void);
|
||||
uint8_t esp_wifi_sta_get_group_cipher_internal(void);
|
||||
int esp_wifi_set_appie_internal(uint8_t type, uint8_t *ie, uint16_t len, uint8_t flag);
|
||||
int esp_wifi_unset_appie_internal(uint8_t type);
|
||||
struct wifi_appie *esp_wifi_get_appie_internal(uint8_t type);
|
||||
bool esp_wifi_auth_done_internal(void);
|
||||
uint16_t esp_wifi_sta_pmf_enabled(void);
|
||||
wifi_cipher_type_t esp_wifi_sta_get_mgmt_group_cipher(void);
|
||||
int esp_wifi_set_igtk_internal(uint8_t if_index, const wifi_wpa_igtk_t *igtk);
|
||||
int esp_wifi_register_wpa_cb_internal(struct wpa_funcs *cb);
|
||||
int esp_wifi_unregister_wpa_cb_internal(void);
|
||||
|
||||
int esp_wifi_get_assoc_bssid_internal(uint8_t *bssid);
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_disable_internal(wifi_wpa2_param_t *param);
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_enable_internal(wifi_wpa2_param_t *param);
|
||||
esp_err_t esp_wifi_set_wpa2_ent_state_internal(wpa2_ent_eap_state_t state);
|
||||
int esp_wifi_register_wpa2_cb_internal(struct wpa2_funcs *cb);
|
||||
int esp_wifi_unregister_wpa2_cb_internal(void);
|
||||
|
||||
int esp_wifi_register_tx_cb_internal(wifi_tx_cb_t fn, u8 id);
|
||||
|
||||
int esp_wifi_get_wps_type_internal(void);
|
||||
int esp_wifi_set_wps_type_internal(uint32_t type);
|
||||
int esp_wifi_get_wps_status_internal(void);
|
||||
int esp_wifi_set_wps_status_internal(uint32_t status);
|
||||
bool esp_wifi_enable_sta_privacy_internal(void);
|
||||
int esp_wifi_disarm_sta_connection_timer_internal(void);
|
||||
int esp_wifi_set_wps_cb_internal(struct wps_funcs *wps_cb);
|
||||
esp_err_t esp_wifi_set_wps_start_flag_internal(bool start);
|
||||
uint8_t esp_wifi_get_user_init_flag_internal(void);
|
||||
|
||||
int esp_wifi_ipc_internal(wifi_ipc_config_t *cfg, bool sync);
|
||||
esp_err_t esp_wifi_internal_issue_disconnect(uint8_t reason_code);
|
||||
int esp_wifi_ap_deauth_internal(uint8_t *mac, uint32_t reason);
|
||||
|
||||
#endif /* _ESP_WIFI_DRIVER_H_ */
|
||||
|
910
components/wpa_supplicant/src/esp_supplicant/esp_wpa2.c
Normal file → Executable file
910
components/wpa_supplicant/src/esp_supplicant/esp_wpa2.c
Normal file → Executable file
@ -43,13 +43,919 @@
|
||||
#endif
|
||||
|
||||
#include "esp_wifi_driver.h"
|
||||
#include "esp_private/wifi.h"
|
||||
#include "esp_wpa_err.h"
|
||||
|
||||
#define WPA2_VERSION "v2.0"
|
||||
|
||||
#define DATA_MUTEX_TAKE() xSemaphoreTakeRecursive(s_wpa2_data_lock,portMAX_DELAY)
|
||||
#define DATA_MUTEX_GIVE() xSemaphoreGiveRecursive(s_wpa2_data_lock)
|
||||
|
||||
static void *s_wpa2_data_lock = NULL;
|
||||
|
||||
static struct eap_sm *gEapSm = NULL;
|
||||
|
||||
static int eap_peer_sm_init(void);
|
||||
static void eap_peer_sm_deinit(void);
|
||||
|
||||
static int eap_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len, uint8_t *bssid);
|
||||
static int wpa2_start_eapol_internal(void);
|
||||
int wpa2_post(uint32_t sig, uint32_t par);
|
||||
|
||||
#ifdef USE_WPA2_TASK
|
||||
static void *s_wpa2_task_hdl = NULL;
|
||||
static void *s_wpa2_queue = NULL;
|
||||
static wpa2_state_t s_wpa2_state = WPA2_STATE_DISABLED;
|
||||
static void *s_wpa2_api_lock = NULL;
|
||||
static void *s_wifi_wpa2_sync_sem = NULL;
|
||||
static bool s_disable_time_check = true;
|
||||
|
||||
extern bool wifi_unregister_wpa2_cb(void);
|
||||
static void wpa2_api_lock(void)
|
||||
{
|
||||
if (s_wpa2_api_lock == NULL) {
|
||||
s_wpa2_api_lock = xSemaphoreCreateRecursiveMutex();
|
||||
if (!s_wpa2_api_lock) {
|
||||
wpa_printf(MSG_ERROR, "WPA2: failed to create wpa2 api lock");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
xSemaphoreTakeRecursive(s_wpa2_api_lock, portMAX_DELAY);
|
||||
}
|
||||
|
||||
static void wpa2_api_unlock(void)
|
||||
{
|
||||
if (s_wpa2_api_lock) {
|
||||
xSemaphoreGiveRecursive(s_wpa2_api_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static bool inline wpa2_is_enabled(void)
|
||||
{
|
||||
return (s_wpa2_state == WPA2_STATE_ENABLED);
|
||||
}
|
||||
|
||||
static bool inline wpa2_is_disabled(void)
|
||||
{
|
||||
return (s_wpa2_state == WPA2_STATE_DISABLED);
|
||||
}
|
||||
|
||||
static void inline wpa2_set_state(wpa2_state_t state)
|
||||
{
|
||||
s_wpa2_state = state;
|
||||
}
|
||||
|
||||
static void wpa2_set_eap_state(wpa2_ent_eap_state_t state)
|
||||
{
|
||||
if (!gEapSm) {
|
||||
return;
|
||||
}
|
||||
|
||||
gEapSm->finish_state = state;
|
||||
esp_wifi_set_wpa2_ent_state_internal(state);
|
||||
}
|
||||
|
||||
static inline void wpa2_task_delete(void *arg)
|
||||
{
|
||||
void *my_task_hdl = xTaskGetCurrentTaskHandle();
|
||||
int ret = ESP_OK;
|
||||
|
||||
if (my_task_hdl == s_wpa2_task_hdl) {
|
||||
wpa_printf(MSG_ERROR, "WPA2: should never call task delete api in wpa2 task context");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = wpa2_post(SIG_WPA2_TASK_DEL, 0);
|
||||
|
||||
if (ESP_OK != ret) {
|
||||
wpa_printf(MSG_ERROR, "WPA2: failed to post task delete event, ret=%d", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#define WPA_ADDR_LEN 6
|
||||
struct wpa2_rx_param {
|
||||
uint8_t *bssid;
|
||||
u8 sa[WPA_ADDR_LEN];
|
||||
u8 *buf;
|
||||
int len;
|
||||
STAILQ_ENTRY(wpa2_rx_param) bqentry;
|
||||
};
|
||||
static STAILQ_HEAD(, wpa2_rx_param) s_wpa2_rxq;
|
||||
|
||||
static void wpa2_rxq_init(void)
|
||||
{
|
||||
DATA_MUTEX_TAKE();
|
||||
STAILQ_INIT(&s_wpa2_rxq);
|
||||
DATA_MUTEX_GIVE();
|
||||
}
|
||||
|
||||
static void wpa2_rxq_enqueue(struct wpa2_rx_param *param)
|
||||
{
|
||||
DATA_MUTEX_TAKE();
|
||||
STAILQ_INSERT_TAIL(&s_wpa2_rxq,param, bqentry);
|
||||
DATA_MUTEX_GIVE();
|
||||
}
|
||||
|
||||
static struct wpa2_rx_param * wpa2_rxq_dequeue(void)
|
||||
{
|
||||
struct wpa2_rx_param *param = NULL;
|
||||
DATA_MUTEX_TAKE();
|
||||
if ((param = STAILQ_FIRST(&s_wpa2_rxq)) != NULL) {
|
||||
STAILQ_REMOVE_HEAD(&s_wpa2_rxq, bqentry);
|
||||
STAILQ_NEXT(param,bqentry) = NULL;
|
||||
}
|
||||
DATA_MUTEX_GIVE();
|
||||
return param;
|
||||
}
|
||||
|
||||
static void wpa2_rxq_deinit(void)
|
||||
{
|
||||
struct wpa2_rx_param *param = NULL;
|
||||
DATA_MUTEX_TAKE();
|
||||
while ((param = STAILQ_FIRST(&s_wpa2_rxq)) != NULL) {
|
||||
STAILQ_REMOVE_HEAD(&s_wpa2_rxq, bqentry);
|
||||
STAILQ_NEXT(param,bqentry) = NULL;
|
||||
os_free(param->buf);
|
||||
os_free(param);
|
||||
}
|
||||
DATA_MUTEX_GIVE();
|
||||
}
|
||||
|
||||
void wpa2_task(void *pvParameters )
|
||||
{
|
||||
ETSEvent *e;
|
||||
struct eap_sm *sm = gEapSm;
|
||||
bool task_del = false;
|
||||
|
||||
if (!sm) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if ( pdPASS == xQueueReceive(s_wpa2_queue, &e, portMAX_DELAY) ) {
|
||||
if (e->sig < SIG_WPA2_MAX) {
|
||||
DATA_MUTEX_TAKE();
|
||||
if(sm->wpa2_sig_cnt[e->sig]) {
|
||||
sm->wpa2_sig_cnt[e->sig]--;
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "wpa2_task: invalid sig cnt, sig=%d cnt=%d", e->sig, sm->wpa2_sig_cnt[e->sig]);
|
||||
}
|
||||
DATA_MUTEX_GIVE();
|
||||
}
|
||||
switch (e->sig) {
|
||||
case SIG_WPA2_TASK_DEL:
|
||||
task_del = true;
|
||||
break;
|
||||
case SIG_WPA2_START:
|
||||
wpa2_start_eapol_internal();
|
||||
break;
|
||||
case SIG_WPA2_RX: {
|
||||
struct wpa2_rx_param *param = NULL;
|
||||
|
||||
while ((param = wpa2_rxq_dequeue()) != NULL){
|
||||
eap_sm_rx_eapol_internal(param->sa, param->buf, param->len, param->bssid);
|
||||
os_free(param->buf);
|
||||
os_free(param);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
os_free(e);
|
||||
}
|
||||
|
||||
if (task_del) {
|
||||
break;
|
||||
} else {
|
||||
if (s_wifi_wpa2_sync_sem) {
|
||||
wpa_printf(MSG_DEBUG, "WPA2: wifi->wpa2 api completed sig(%d)", e->sig);
|
||||
xSemaphoreGive(s_wifi_wpa2_sync_sem);
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "WPA2: null wifi->wpa2 sync sem");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "WPA2: queue deleted");
|
||||
vQueueDelete(s_wpa2_queue);
|
||||
wpa_printf(MSG_DEBUG, "WPA2: task deleted");
|
||||
s_wpa2_queue = NULL;
|
||||
if (s_wifi_wpa2_sync_sem) {
|
||||
wpa_printf(MSG_DEBUG, "WPA2: wifi->wpa2 api completed sig(%d)", e->sig);
|
||||
xSemaphoreGive(s_wifi_wpa2_sync_sem);
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "WPA2: null wifi->wpa2 sync sem");
|
||||
}
|
||||
|
||||
/* At this point, we completed */
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
int wpa2_post(uint32_t sig, uint32_t par)
|
||||
{
|
||||
struct eap_sm *sm = gEapSm;
|
||||
|
||||
if (!sm) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
DATA_MUTEX_TAKE();
|
||||
if (sm->wpa2_sig_cnt[sig]) {
|
||||
DATA_MUTEX_GIVE();
|
||||
return ESP_OK;
|
||||
} else {
|
||||
ETSEvent *evt = (ETSEvent *)os_malloc(sizeof(ETSEvent));
|
||||
if (evt == NULL) {
|
||||
wpa_printf(MSG_ERROR, "WPA2: E N M\n");
|
||||
DATA_MUTEX_GIVE();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
sm->wpa2_sig_cnt[sig]++;
|
||||
DATA_MUTEX_GIVE();
|
||||
evt->sig = sig;
|
||||
evt->par = par;
|
||||
if ( xQueueSend(s_wpa2_queue, &evt, 10 / portTICK_PERIOD_MS ) != pdPASS) {
|
||||
wpa_printf(MSG_ERROR, "WPA2: Q S E");
|
||||
return ESP_FAIL;
|
||||
} else {
|
||||
if (s_wifi_wpa2_sync_sem) {
|
||||
xSemaphoreTake(s_wifi_wpa2_sync_sem, portMAX_DELAY);
|
||||
wpa_printf(MSG_DEBUG, "WPA2: wpa2 api return, sm->state(%d)", sm->finish_state);
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "WPA2: null wifi->wpa2 sync sem");
|
||||
}
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif /* USE_WPA2_TASK */
|
||||
|
||||
static void wpa2_sendto_wrapper(void *buffer, uint16_t len)
|
||||
{
|
||||
esp_wifi_internal_tx(WIFI_IF_STA, buffer, len);
|
||||
}
|
||||
|
||||
static inline int wpa2_sm_ether_send(struct eap_sm *sm, const u8 *dest, u16 proto,
|
||||
const u8 *data, size_t data_len)
|
||||
{
|
||||
void *buffer = (void *)(data - sizeof(struct l2_ethhdr));
|
||||
struct l2_ethhdr *eth = NULL;
|
||||
|
||||
if (!buffer) {
|
||||
wpa_printf(MSG_ERROR, "wpa2: invalid data");
|
||||
return ESP_FAIL;
|
||||
} else {
|
||||
eth = (struct l2_ethhdr *)buffer;
|
||||
memcpy(eth->h_dest, dest, ETH_ALEN);
|
||||
memcpy(eth->h_source, sm->ownaddr, ETH_ALEN);
|
||||
eth->h_proto = host_to_be16(proto);
|
||||
wpa2_sendto_wrapper(buffer, sizeof(struct l2_ethhdr) + data_len);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
u8 *wpa2_sm_alloc_eapol(struct eap_sm *sm, u8 type,
|
||||
const void *data, u16 data_len,
|
||||
size_t *msg_len, void **data_pos)
|
||||
{
|
||||
void *buffer;
|
||||
struct ieee802_1x_hdr *hdr;
|
||||
|
||||
*msg_len = sizeof(struct ieee802_1x_hdr) + data_len;
|
||||
/* XXX: reserve l2_ethhdr is enough */
|
||||
buffer = os_malloc(*msg_len + sizeof(struct l2_ethhdr));
|
||||
|
||||
if (buffer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hdr = (struct ieee802_1x_hdr *)((char *)buffer + sizeof(struct l2_ethhdr));
|
||||
hdr->version = 0x01;
|
||||
hdr->type = type;
|
||||
hdr->length = host_to_be16(data_len);
|
||||
|
||||
if (data) {
|
||||
memcpy(hdr + 1, data, data_len);
|
||||
} else {
|
||||
memset(hdr + 1, 0, data_len);
|
||||
}
|
||||
|
||||
if (data_pos) {
|
||||
*data_pos = hdr + 1;
|
||||
}
|
||||
|
||||
return (u8 *) hdr;
|
||||
}
|
||||
|
||||
|
||||
void wpa2_sm_free_eapol(u8 *buffer)
|
||||
{
|
||||
if (buffer != NULL) {
|
||||
buffer = buffer - sizeof(struct l2_ethhdr);
|
||||
os_free(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int eap_sm_send_eapol(struct eap_sm *sm, struct wpabuf *resp)
|
||||
{
|
||||
size_t outlen;
|
||||
int ret;
|
||||
u8 *outbuf = NULL;
|
||||
|
||||
u8 bssid[6];
|
||||
ret = esp_wifi_get_assoc_bssid_internal(bssid);
|
||||
|
||||
if (ret != 0) {
|
||||
wpa_printf(MSG_DEBUG, "bssid is empty \n");
|
||||
return WPA_ERR_INVALID_BSSID;
|
||||
}
|
||||
|
||||
outbuf = wpa2_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET,
|
||||
wpabuf_head_u8(resp), wpabuf_len(resp),
|
||||
&outlen, NULL);
|
||||
if (!outbuf) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
ret = wpa2_sm_ether_send(sm, bssid, ETH_P_EAPOL, outbuf, outlen);
|
||||
wpa2_sm_free_eapol(outbuf);
|
||||
if (ret) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int eap_sm_process_request(struct eap_sm *sm, struct wpabuf *reqData)
|
||||
{
|
||||
size_t plen;
|
||||
u32 reqVendor, reqVendorMethod;
|
||||
u8 type, *pos;
|
||||
struct eap_hdr *ehdr;
|
||||
const struct eap_method *m = NULL;
|
||||
struct wpabuf *resp = NULL;
|
||||
struct eap_method_ret m_res;
|
||||
int ret = 0;
|
||||
|
||||
if (reqData == NULL || wpabuf_len(reqData) < sizeof(*ehdr)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ehdr = (struct eap_hdr *)wpabuf_head(reqData);
|
||||
plen = be_to_host16(ehdr->length);
|
||||
if (plen > wpabuf_len(reqData)) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (ehdr->identifier == sm->current_identifier) {
|
||||
/*Retransmit*/
|
||||
resp = sm->lastRespData;
|
||||
goto send_resp;
|
||||
}
|
||||
|
||||
sm->current_identifier = ehdr->identifier;
|
||||
|
||||
pos = (u8 *)(ehdr + 1);
|
||||
type = *pos++;
|
||||
if (type == EAP_TYPE_IDENTITY) {
|
||||
resp = (struct wpabuf *)eap_sm_build_identity_resp(sm, ehdr->identifier, 0);
|
||||
goto send_resp;
|
||||
} else if (type == EAP_TYPE_NOTIFICATION) {
|
||||
/*Ignore*/
|
||||
goto out;
|
||||
} else if (type == EAP_TYPE_EXPANDED) {
|
||||
if (plen < sizeof(*ehdr) + 8) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
reqVendor = WPA_GET_BE24(pos);
|
||||
pos += 3;
|
||||
reqVendorMethod = WPA_GET_BE32(pos);
|
||||
} else {
|
||||
reqVendor = EAP_VENDOR_IETF;
|
||||
reqVendorMethod = type;
|
||||
}
|
||||
|
||||
if (sm->m && sm->m->process && sm->eap_method_priv &&
|
||||
reqVendor == sm->m->vendor &&
|
||||
reqVendorMethod == sm->m->method) {
|
||||
resp = sm->m->process(sm, sm->eap_method_priv,
|
||||
&m_res, reqData);
|
||||
} else {
|
||||
m = eap_peer_get_eap_method(reqVendor, reqVendorMethod);
|
||||
if (m == NULL) {
|
||||
goto build_nak;
|
||||
}
|
||||
if (sm->m) {
|
||||
eap_deinit_prev_method(sm, "GET_METHOD");
|
||||
}
|
||||
sm->m = m;
|
||||
sm->eap_method_priv = sm->m->init(sm);
|
||||
if (sm->eap_method_priv == NULL) {
|
||||
wpa_printf(MSG_ERROR, "Method private structure allocated failure\n");
|
||||
sm->m = NULL;
|
||||
goto build_nak;
|
||||
}
|
||||
|
||||
if (sm->m->process) {
|
||||
resp = sm->m->process(sm, sm->eap_method_priv, &m_res, reqData);
|
||||
}
|
||||
}
|
||||
|
||||
if (sm->m->isKeyAvailable && sm->m->getKey &&
|
||||
sm->m->isKeyAvailable(sm, sm->eap_method_priv)) {
|
||||
if (sm->eapKeyData) {
|
||||
os_free(sm->eapKeyData);
|
||||
}
|
||||
sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv,
|
||||
&sm->eapKeyDataLen);
|
||||
}
|
||||
goto send_resp;
|
||||
|
||||
build_nak:
|
||||
resp = (struct wpabuf *)eap_sm_build_nak(sm, type, ehdr->identifier);
|
||||
if (resp == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ret = ESP_FAIL;
|
||||
|
||||
send_resp:
|
||||
if (resp == NULL) {
|
||||
wpa_printf(MSG_ERROR, "Response build fail, return.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ret = eap_sm_send_eapol(sm, resp);
|
||||
if (ret == ESP_OK) {
|
||||
if (resp != sm->lastRespData) {
|
||||
wpabuf_free(sm->lastRespData);
|
||||
sm->lastRespData = resp;
|
||||
}
|
||||
} else {
|
||||
wpabuf_free(sm->lastRespData);
|
||||
sm->lastRespData = NULL;
|
||||
wpabuf_free(resp);
|
||||
resp = NULL;
|
||||
|
||||
if (ret == WPA_ERR_INVALID_BSSID) {
|
||||
ret = WPA2_ENT_EAP_STATE_FAIL;
|
||||
wpa2_set_eap_state(WPA2_ENT_EAP_STATE_FAIL);
|
||||
}
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int eap_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len, uint8_t *bssid)
|
||||
{
|
||||
struct eap_sm *sm = gEapSm;
|
||||
|
||||
if (!sm) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#ifdef USE_WPA2_TASK
|
||||
{
|
||||
struct wpa2_rx_param *param = (struct wpa2_rx_param *)os_zalloc(sizeof(struct wpa2_rx_param)); /* free in task */
|
||||
|
||||
if (!param) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
param->buf = (u8 *)os_zalloc(len); /* free in task */
|
||||
if (!param->buf) {
|
||||
os_free(param);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
param->bssid = bssid;
|
||||
memcpy(param->buf, buf, len);
|
||||
param->len = len;
|
||||
memcpy(param->sa, src_addr, WPA_ADDR_LEN);
|
||||
|
||||
wpa2_rxq_enqueue(param);
|
||||
return wpa2_post(SIG_WPA2_RX, 0);
|
||||
}
|
||||
#else
|
||||
|
||||
return eap_sm_rx_eapol_internal(src_addr, buf, len, bssid);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int wpa2_ent_rx_eapol(u8 *src_addr, u8 *buf, u32 len, uint8_t *bssid)
|
||||
{
|
||||
struct ieee802_1x_hdr *hdr;
|
||||
int ret = ESP_OK;
|
||||
|
||||
hdr = (struct ieee802_1x_hdr *) buf;
|
||||
|
||||
switch (hdr->type) {
|
||||
case IEEE802_1X_TYPE_EAPOL_START:
|
||||
case IEEE802_1X_TYPE_EAP_PACKET:
|
||||
case IEEE802_1X_TYPE_EAPOL_LOGOFF:
|
||||
ret = eap_sm_rx_eapol(src_addr, buf, len, bssid);
|
||||
break;
|
||||
case IEEE802_1X_TYPE_EAPOL_KEY:
|
||||
ret = wpa_sm_rx_eapol(src_addr, buf, len);
|
||||
break;
|
||||
default:
|
||||
wpa_printf(MSG_ERROR, "Unknown EAPOL packet type - %d\n", hdr->type);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int eap_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len, uint8_t *bssid)
|
||||
{
|
||||
struct eap_sm *sm = gEapSm;
|
||||
u32 plen, data_len;
|
||||
struct ieee802_1x_hdr *hdr;
|
||||
struct eap_hdr *ehdr;
|
||||
struct wpabuf *req = NULL;
|
||||
u8 *tmp;
|
||||
int ret = ESP_FAIL;
|
||||
|
||||
if (!sm) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (len < sizeof(*hdr) + sizeof(*ehdr)) {
|
||||
#ifdef DEBUG_PRINT
|
||||
wpa_printf(MSG_DEBUG, "WPA: EAPOL frame too short to be a WPA "
|
||||
"EAPOL-Key (len %lu, expecting at least %lu)",
|
||||
(unsigned long) len,
|
||||
(unsigned long) sizeof(*hdr) + sizeof(*ehdr));
|
||||
#endif
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
tmp = buf;
|
||||
|
||||
hdr = (struct ieee802_1x_hdr *) tmp;
|
||||
ehdr = (struct eap_hdr *) (hdr + 1);
|
||||
plen = be_to_host16(hdr->length);
|
||||
data_len = plen + sizeof(*hdr);
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
wpa_printf(MSG_DEBUG, "IEEE 802.1X RX: version=%d type=%d length=%d\n",
|
||||
hdr->version, hdr->type, plen);
|
||||
#endif
|
||||
if (hdr->version < EAPOL_VERSION) {
|
||||
/* TODO: backwards compatibility */
|
||||
}
|
||||
if (hdr->type != IEEE802_1X_TYPE_EAP_PACKET) {
|
||||
#ifdef DEBUG_PRINT
|
||||
wpa_printf(MSG_DEBUG, "WPA2: EAP frame (type %u) discarded, "
|
||||
"not a EAP PACKET frame", hdr->type);
|
||||
#endif
|
||||
ret = -2;
|
||||
goto _out;
|
||||
}
|
||||
if (plen > len - sizeof(*hdr) || plen < sizeof(*ehdr)) {
|
||||
#ifdef DEBUG_PRINT
|
||||
wpa_printf(MSG_DEBUG, "WPA2: EAPOL frame payload size %lu "
|
||||
"invalid (frame size %lu)",
|
||||
(unsigned long) plen, (unsigned long) len);
|
||||
#endif
|
||||
ret = -2;
|
||||
goto _out;
|
||||
}
|
||||
|
||||
wpa_hexdump(MSG_MSGDUMP, "WPA2: RX EAPOL-EAP PACKET", tmp, len);
|
||||
|
||||
if (data_len < len) {
|
||||
#ifdef DEBUG_PRINT
|
||||
wpa_printf(MSG_DEBUG, "WPA: ignoring %lu bytes after the IEEE "
|
||||
"802.1X data\n", (unsigned long) len - data_len);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef EAP_PEER_METHOD
|
||||
switch (ehdr->code) {
|
||||
case EAP_CODE_REQUEST:
|
||||
/* Handle EAP-reauthentication case */
|
||||
if (sm->finish_state == WPA2_ENT_EAP_STATE_SUCCESS) {
|
||||
wpa_printf(MSG_INFO, ">>>>>wpa2 EAP Re-authentication in progress\n");
|
||||
wpa2_set_eap_state(WPA2_ENT_EAP_STATE_IN_PROGRESS);
|
||||
}
|
||||
|
||||
req = wpabuf_alloc_copy((u8 *)ehdr, len - sizeof(*hdr));
|
||||
ret = eap_sm_process_request(sm, req);
|
||||
break;
|
||||
case EAP_CODE_RESPONSE:
|
||||
/*Ignore*/
|
||||
break;
|
||||
case EAP_CODE_SUCCESS:
|
||||
if (sm->eapKeyData) {
|
||||
wpa_set_pmk(sm->eapKeyData, NULL, false);
|
||||
os_free(sm->eapKeyData);
|
||||
sm->eapKeyData = NULL;
|
||||
wpa_printf(MSG_INFO, ">>>>>wpa2 FINISH\n");
|
||||
ret = WPA2_ENT_EAP_STATE_SUCCESS;
|
||||
wpa2_set_eap_state(WPA2_ENT_EAP_STATE_SUCCESS);
|
||||
eap_deinit_prev_method(sm, "EAP Success");
|
||||
} else {
|
||||
wpa_printf(MSG_INFO, ">>>>>wpa2 FAILED, receive EAP_SUCCESS but pmk is empty, potential attack!\n");
|
||||
ret = WPA2_ENT_EAP_STATE_FAIL;
|
||||
wpa2_set_eap_state(WPA2_ENT_EAP_STATE_FAIL);
|
||||
}
|
||||
break;
|
||||
case EAP_CODE_FAILURE:
|
||||
wpa_printf(MSG_INFO, ">>>>>wpa2 FAILED\n");
|
||||
ret = WPA2_ENT_EAP_STATE_FAIL;
|
||||
wpa2_set_eap_state(WPA2_ENT_EAP_STATE_FAIL);
|
||||
break;
|
||||
}
|
||||
_out:
|
||||
wpabuf_free(req);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wpa2_start_eapol(void)
|
||||
{
|
||||
#ifdef USE_WPA2_TASK
|
||||
return wpa2_post(SIG_WPA2_START, 0);
|
||||
#else
|
||||
return wpa2_start_eapol_internal();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int wpa2_start_eapol_internal(void)
|
||||
{
|
||||
struct eap_sm *sm = gEapSm;
|
||||
int ret = 0;
|
||||
u8 bssid[6];
|
||||
u8 *buf;
|
||||
size_t len;
|
||||
|
||||
if (!sm) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (wpa_sta_cur_pmksa_matches_akm()) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"RSN: PMKSA caching - do not send EAPOL-Start");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ret = esp_wifi_get_assoc_bssid_internal(bssid);
|
||||
if (ret != 0) {
|
||||
wpa_printf(MSG_ERROR, "bssid is empty!");
|
||||
return WPA_ERR_INVALID_BSSID;
|
||||
}
|
||||
|
||||
buf = wpa2_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START, (u8 *)"", 0, &len, NULL);
|
||||
if (!buf) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
wpa2_set_eap_state(WPA2_ENT_EAP_STATE_IN_PROGRESS);
|
||||
wpa2_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
|
||||
wpa2_sm_free_eapol(buf);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* eap_peer_sm_init - Allocate and initialize EAP peer state machine
|
||||
* @eapol_ctx: Context data to be used with eapol_cb calls
|
||||
* @eapol_cb: Pointer to EAPOL callback functions
|
||||
* @msg_ctx: Context data for wpa_msg() calls
|
||||
* @conf: EAP configuration
|
||||
* Returns: Pointer to the allocated EAP state machine or %NULL on failure
|
||||
*
|
||||
* This function allocates and initializes an EAP state machine. In addition,
|
||||
* this initializes TLS library for the new EAP state machine. eapol_cb pointer
|
||||
* will be in use until eap_peer_sm_deinit() is used to deinitialize this EAP
|
||||
* state machine. Consequently, the caller must make sure that this data
|
||||
* structure remains alive while the EAP state machine is active.
|
||||
*/
|
||||
static int eap_peer_sm_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
struct eap_sm *sm;
|
||||
|
||||
if (gEapSm) {
|
||||
wpa_printf(MSG_ERROR, "WPA2: wpa2 sm not null, deinit it");
|
||||
eap_peer_sm_deinit();
|
||||
}
|
||||
|
||||
sm = (struct eap_sm *)os_zalloc(sizeof(*sm));
|
||||
if (sm == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
s_wpa2_data_lock = xSemaphoreCreateRecursiveMutex();
|
||||
if (!s_wpa2_data_lock) {
|
||||
wpa_printf(MSG_ERROR, "wpa2 eap_peer_sm_init: failed to alloc data lock"); // NOLINT(clang-analyzer-unix.Malloc)
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
wpa2_set_eap_state(WPA2_ENT_EAP_STATE_NOT_START);
|
||||
sm->current_identifier = 0xff;
|
||||
esp_wifi_get_macaddr_internal(WIFI_IF_STA, sm->ownaddr);
|
||||
ret = eap_peer_blob_init(sm);
|
||||
if (ret) {
|
||||
wpa_printf(MSG_ERROR, "eap_peer_blob_init failed\n");
|
||||
os_free(sm);
|
||||
vSemaphoreDelete(s_wpa2_data_lock);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ret = eap_peer_config_init(sm, g_wpa_private_key_passwd, g_wpa_private_key_passwd_len);
|
||||
if (ret) {
|
||||
wpa_printf(MSG_ERROR, "eap_peer_config_init failed\n");
|
||||
eap_peer_blob_deinit(sm);
|
||||
os_free(sm);
|
||||
vSemaphoreDelete(s_wpa2_data_lock);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
sm->ssl_ctx = tls_init();
|
||||
if (sm->ssl_ctx == NULL) {
|
||||
wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS "
|
||||
"context.");
|
||||
eap_peer_blob_deinit(sm);
|
||||
eap_peer_config_deinit(sm);
|
||||
os_free(sm);
|
||||
vSemaphoreDelete(s_wpa2_data_lock);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
wpa2_rxq_init();
|
||||
|
||||
gEapSm = sm;
|
||||
#ifdef USE_WPA2_TASK
|
||||
s_wpa2_queue = xQueueCreate(SIG_WPA2_MAX, sizeof( void * ) );
|
||||
xTaskCreate(wpa2_task, "wpa2T", WPA2_TASK_STACK_SIZE, NULL, 2, &s_wpa2_task_hdl);
|
||||
s_wifi_wpa2_sync_sem = xSemaphoreCreateCounting(1, 0);
|
||||
if (!s_wifi_wpa2_sync_sem) {
|
||||
vQueueDelete(s_wpa2_queue);
|
||||
s_wpa2_queue = NULL;
|
||||
eap_peer_blob_deinit(sm);
|
||||
eap_peer_config_deinit(sm);
|
||||
os_free(sm);
|
||||
vSemaphoreDelete(s_wpa2_data_lock);
|
||||
wpa_printf(MSG_ERROR, "WPA2: failed create wifi wpa2 task sync sem");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_INFO, "wpa2_task prio:%d, stack:%d\n", 2, WPA2_TASK_STACK_SIZE);
|
||||
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* eap_peer_sm_deinit - Deinitialize and free an EAP peer state machine
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
*
|
||||
* This function deinitializes EAP state machine and frees all allocated
|
||||
* resources.
|
||||
*/
|
||||
static void eap_peer_sm_deinit(void)
|
||||
{
|
||||
struct eap_sm *sm = gEapSm;
|
||||
|
||||
if (sm == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
eap_peer_config_deinit(sm);
|
||||
eap_peer_blob_deinit(sm);
|
||||
eap_deinit_prev_method(sm, "EAP deinit");
|
||||
eap_sm_abort(sm);
|
||||
tls_deinit(sm->ssl_ctx);
|
||||
#ifdef USE_WPA2_TASK
|
||||
wpa2_task_delete(0);
|
||||
#endif
|
||||
|
||||
if (STAILQ_FIRST((&s_wpa2_rxq)) != NULL) {
|
||||
wpa2_rxq_deinit();
|
||||
}
|
||||
|
||||
if (s_wifi_wpa2_sync_sem) {
|
||||
vSemaphoreDelete(s_wifi_wpa2_sync_sem);
|
||||
}
|
||||
s_wifi_wpa2_sync_sem = NULL;
|
||||
|
||||
if (s_wpa2_data_lock) {
|
||||
vSemaphoreDelete(s_wpa2_data_lock);
|
||||
s_wpa2_data_lock = NULL;
|
||||
wpa_printf(MSG_DEBUG, "wpa2 eap_peer_sm_deinit: free data lock");
|
||||
}
|
||||
|
||||
os_free(sm);
|
||||
gEapSm = NULL;
|
||||
}
|
||||
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_enable_fn(void *arg)
|
||||
{
|
||||
struct wpa2_funcs *wpa2_cb;
|
||||
|
||||
wpa_printf(MSG_INFO, "WPA2 ENTERPRISE VERSION: [%s] enable\n",
|
||||
WPA2_VERSION);
|
||||
|
||||
wpa2_cb = (struct wpa2_funcs *)os_zalloc(sizeof(struct wpa2_funcs));
|
||||
if (wpa2_cb == NULL) {
|
||||
wpa_printf(MSG_ERROR, "WPA2: no mem for wpa2 cb\n");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
wpa2_cb->wpa2_sm_rx_eapol = wpa2_ent_rx_eapol;
|
||||
wpa2_cb->wpa2_start = wpa2_start_eapol;
|
||||
wpa2_cb->wpa2_init = eap_peer_sm_init;
|
||||
wpa2_cb->wpa2_deinit = eap_peer_sm_deinit;
|
||||
|
||||
esp_wifi_register_wpa2_cb_internal(wpa2_cb);
|
||||
|
||||
wpa_printf(MSG_DEBUG, "WPA2 ENTERPRISE CRYPTO INIT.\r\n");
|
||||
|
||||
#ifdef EAP_PEER_METHOD
|
||||
if (eap_peer_register_methods()) {
|
||||
wpa_printf(MSG_ERROR, "Register EAP Peer methods Failure\n");
|
||||
}
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_enable(void)
|
||||
{
|
||||
wifi_wpa2_param_t param;
|
||||
esp_err_t ret;
|
||||
|
||||
wpa2_api_lock();
|
||||
|
||||
if (wpa2_is_enabled()) {
|
||||
wpa_printf(MSG_INFO, "WPA2: already enabled");
|
||||
wpa2_api_unlock();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
param.fn = (wifi_wpa2_fn_t)esp_wifi_sta_wpa2_ent_enable_fn;
|
||||
param.param = NULL;
|
||||
|
||||
ret = esp_wifi_sta_wpa2_ent_enable_internal(¶m);
|
||||
|
||||
if (ESP_OK == ret) {
|
||||
wpa2_set_state(WPA2_STATE_ENABLED);
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "failed to enable wpa2 ret=%d", ret);
|
||||
}
|
||||
|
||||
wpa2_api_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_disable_fn(void *param)
|
||||
{
|
||||
wpa_printf(MSG_INFO, "WPA2 ENTERPRISE VERSION: [%s] disable\n", WPA2_VERSION);
|
||||
esp_wifi_unregister_wpa2_cb_internal();
|
||||
|
||||
if (gEapSm) {
|
||||
eap_peer_sm_deinit();
|
||||
}
|
||||
|
||||
#ifdef USE_WPA2_TASK
|
||||
#endif
|
||||
|
||||
#ifdef EAP_PEER_METHOD
|
||||
eap_peer_unregister_methods();
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_disable(void)
|
||||
{
|
||||
wifi_wpa2_param_t param;
|
||||
esp_err_t ret;
|
||||
|
||||
wpa2_api_lock();
|
||||
|
||||
if (wpa2_is_disabled()) {
|
||||
wpa_printf(MSG_INFO, "WPA2: already disabled");
|
||||
wpa2_api_unlock();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
param.fn = (wifi_wpa2_fn_t)esp_wifi_sta_wpa2_ent_disable_fn;
|
||||
param.param = 0;
|
||||
ret = esp_wifi_sta_wpa2_ent_disable_internal(¶m);
|
||||
|
||||
if (ESP_OK == ret) {
|
||||
wpa2_set_state(WPA2_STATE_DISABLED);
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "failed to disable wpa2 ret=%d", ret);
|
||||
}
|
||||
|
||||
wpa2_api_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_set_cert_key(const unsigned char *client_cert, int client_cert_len, const unsigned char *private_key, int private_key_len, const unsigned char *private_key_passwd, int private_key_passwd_len)
|
||||
{
|
||||
@ -71,7 +977,7 @@ esp_err_t esp_wifi_sta_wpa2_ent_set_cert_key(const unsigned char *client_cert, i
|
||||
|
||||
void esp_wifi_sta_wpa2_ent_clear_cert_key(void)
|
||||
{
|
||||
wifi_unregister_wpa2_cb();
|
||||
esp_wifi_unregister_wpa2_cb_internal();
|
||||
|
||||
g_wpa_client_cert = NULL;
|
||||
g_wpa_client_cert_len = 0;
|
||||
|
@ -32,7 +32,7 @@ static esp_err_t wpa3_build_sae_commit(u8 *bssid)
|
||||
u8 own_addr[ETH_ALEN];
|
||||
const u8 *pw;
|
||||
|
||||
if (wpa_sta_is_cur_pmksa_set()) {
|
||||
if (wpa_sta_cur_pmksa_matches_akm()) {
|
||||
wpa_printf(MSG_INFO, "wpa3: Skip SAE and use cached PMK instead");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@ -130,7 +130,7 @@ void esp_wpa3_free_sae_data(void)
|
||||
sae_clear_data(&g_sae_data);
|
||||
}
|
||||
|
||||
u8 *wpa3_build_sae_msg(u8 *bssid, u32 sae_msg_type, u32 *sae_msg_len)
|
||||
static u8 *wpa3_build_sae_msg(u8 *bssid, u32 sae_msg_type, u32 *sae_msg_len)
|
||||
{
|
||||
u8 *buf = NULL;
|
||||
|
||||
@ -201,12 +201,11 @@ static int wpa3_parse_sae_confirm(u8 *buf, u32 len)
|
||||
g_sae_data.state = SAE_ACCEPTED;
|
||||
|
||||
wpa_set_pmk(g_sae_data.pmk, g_sae_data.pmkid, true);
|
||||
memcpy(esp_wifi_sta_get_ap_info_prof_pmk_internal(), g_sae_data.pmk, PMK_LEN);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int wpa3_parse_sae_msg(u8 *buf, u32 len, u32 sae_msg_type, u16 status)
|
||||
static int wpa3_parse_sae_msg(u8 *buf, u32 len, u32 sae_msg_type, u16 status)
|
||||
{
|
||||
int ret = ESP_OK;
|
||||
|
||||
@ -226,15 +225,11 @@ int wpa3_parse_sae_msg(u8 *buf, u32 len, u32 sae_msg_type, u16 status)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
u8 *wpa3_build_sae_msg(u8 *bssid, u32 sae_msg_type, u32 *sae_msg_len)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int wpa3_parse_sae_msg(u8 *buf, u32 len, u32 sae_msg_type, u16 status)
|
||||
void esp_wifi_register_wpa3_cb(struct wpa_funcs *wpa_cb)
|
||||
{
|
||||
return ESP_FAIL;
|
||||
wpa_cb->wpa3_build_sae_msg = wpa3_build_sae_msg;
|
||||
wpa_cb->wpa3_parse_sae_msg = wpa3_parse_sae_msg;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_WPA3_SAE */
|
||||
|
@ -20,9 +20,16 @@
|
||||
|
||||
#ifdef CONFIG_WPA3_SAE
|
||||
|
||||
void esp_wifi_register_wpa3_cb(struct wpa_funcs *wpa_cb);
|
||||
void esp_wpa3_free_sae_data(void);
|
||||
|
||||
#else /* CONFIG_WPA3_SAE */
|
||||
|
||||
static inline void esp_wifi_register_wpa3_cb(struct wpa_funcs *wpa_cb)
|
||||
{
|
||||
wpa_cb->wpa3_build_sae_msg = NULL;
|
||||
wpa_cb->wpa3_parse_sae_msg = NULL;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_WPA3_SAE */
|
||||
#endif /* ESP_WPA3_H */
|
||||
|
@ -19,20 +19,21 @@
|
||||
#include "common/eapol_common.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "rsn_supp/wpa_ie.h"
|
||||
#include "ap/wpa_auth.h"
|
||||
#include "ap/wpa_auth_i.h"
|
||||
#include "ap/ap_config.h"
|
||||
#include "ap/hostapd.h"
|
||||
#include "esp_wpas_glue.h"
|
||||
#include "esp_hostap.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/sha1.h"
|
||||
#include "crypto/aes_wrap.h"
|
||||
#include "esp_supplicant/esp_wpas_glue.h"
|
||||
|
||||
#include "esp_wifi_driver.h"
|
||||
#define LOCAL static
|
||||
|
||||
extern struct ieee80211_cipher tkip;
|
||||
extern struct ieee80211_cipher ccmp;
|
||||
extern struct ieee80211_cipher wep;
|
||||
|
||||
extern bool dhcpc_flag;
|
||||
|
||||
#include "esp_private/wifi.h"
|
||||
#include "esp_wpa3_i.h"
|
||||
|
||||
void wpa_install_key(enum wpa_alg alg, u8 *addr, int key_idx, int set_tx,
|
||||
u8 *seq, size_t seq_len, u8 *key, size_t key_len, int key_entry_valid)
|
||||
@ -58,48 +59,12 @@ int wpa_get_key(uint8_t *ifx, int *alg, u8 *addr, int *key_idx,
|
||||
* been completed successfully since WPA-PSK does not use EAP state machine.
|
||||
*/
|
||||
|
||||
#include "esp_aio.h"
|
||||
#define EP_OFFSET 36
|
||||
int ieee80211_output_pbuf(esp_aio_t *aio);
|
||||
/* fix buf for tx for now */
|
||||
#define WPA_TX_MSG_BUFF_MAXLEN 200
|
||||
|
||||
LOCAL int wpa_send_cb(esp_aio_t* aio)
|
||||
void wpa_sendto_wrapper(void *buffer, u16 len)
|
||||
{
|
||||
char* pb = (char*)aio->arg;
|
||||
|
||||
os_free(pb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wpa_sendto_wrapper(void* dataptr, u16 datalen)
|
||||
{
|
||||
#ifndef IOT_SIP_MODE
|
||||
esp_aio_t aio;
|
||||
|
||||
aio.arg = dataptr - EP_OFFSET;
|
||||
aio.cb = wpa_send_cb;
|
||||
aio.fd = 0;
|
||||
aio.pbuf = (char *)dataptr;
|
||||
aio.len = datalen;
|
||||
aio.ret = 0;
|
||||
|
||||
if (ieee80211_output_pbuf(&aio) != 0) {
|
||||
os_free(dataptr - EP_OFFSET);
|
||||
}
|
||||
|
||||
#else
|
||||
esf_buf* eb = NULL;
|
||||
uint8_t* frm;
|
||||
|
||||
eb = ieee80211_getmgtframe(&frm, sizeof(struct ieee80211_frame), WPA_TX_MSG_BUFF_MAXLEN);
|
||||
os_memcpy(frm, msg, msg_len);
|
||||
// eb->hdr_len = sizeof(struct ieee80211_frame);
|
||||
eb->data_len = msg_len;
|
||||
EBUF_START(eb) = frm;
|
||||
ieee80211_output_pbuf(ic->ic_if0_conn, eb);
|
||||
#endif
|
||||
esp_wifi_internal_tx(0, buffer, len);
|
||||
}
|
||||
|
||||
void wpa_deauthenticate(u8 reason_code)
|
||||
@ -118,19 +83,25 @@ void wpa_config_profile(void)
|
||||
}
|
||||
}
|
||||
|
||||
void wpa_config_bss(uint8_t *bssid)
|
||||
int wpa_config_bss(uint8_t *bssid)
|
||||
{
|
||||
u8 mac[6];
|
||||
int ret = 0;
|
||||
struct wifi_ssid *ssid = esp_wifi_sta_get_prof_ssid_internal();
|
||||
esp_wifi_get_mac(WIFI_IF_STA, mac);
|
||||
u8 mac[6];
|
||||
|
||||
wpa_set_bss((char *)mac, (char *)bssid, esp_wifi_sta_get_pairwise_cipher_internal(), esp_wifi_sta_get_group_cipher_internal(),
|
||||
esp_wifi_get_macaddr_internal(0, mac);
|
||||
ret = wpa_set_bss((char *)mac, (char *)bssid, esp_wifi_sta_get_pairwise_cipher_internal(), esp_wifi_sta_get_group_cipher_internal(),
|
||||
(char *)esp_wifi_sta_get_prof_password_internal(), ssid->ssid, ssid->len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void wpa_config_assoc_ie(u8 proto, u8 *assoc_buf, u32 assoc_wpa_ie_len)
|
||||
{
|
||||
esp_wifi_set_appie_internal(proto, assoc_buf, assoc_wpa_ie_len, 0);
|
||||
if (proto == BIT(0)) {
|
||||
esp_wifi_set_appie_internal(WIFI_APPIE_WPA, assoc_buf, assoc_wpa_ie_len, 1);
|
||||
} else {
|
||||
esp_wifi_set_appie_internal(WIFI_APPIE_RSN, assoc_buf, assoc_wpa_ie_len, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void wpa_neg_complete(void)
|
||||
@ -138,20 +109,130 @@ void wpa_neg_complete(void)
|
||||
esp_wifi_auth_done_internal();
|
||||
}
|
||||
|
||||
void wpa_sta_init()
|
||||
bool wpa_attach(void)
|
||||
{
|
||||
wpa_register(NULL, wpa_sendto_wrapper,
|
||||
bool ret = true;
|
||||
ret = wpa_sm_init(NULL, wpa_sendto_wrapper,
|
||||
wpa_config_assoc_ie, wpa_install_key, wpa_get_key, wpa_deauthenticate, wpa_neg_complete);
|
||||
if(ret) {
|
||||
ret = (esp_wifi_register_tx_cb_internal(eapol_txcb, WIFI_TXCB_EAPOL_ID) == ESP_OK);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void wpa_sta_deinit(void)
|
||||
uint8_t *wpa_ap_get_wpa_ie(uint8_t *ie_len)
|
||||
{
|
||||
struct hostapd_data *hapd = (struct hostapd_data *)esp_wifi_get_hostap_private_internal();
|
||||
|
||||
if (!hapd || !hapd->wpa_auth || !hapd->wpa_auth->wpa_ie) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*ie_len = hapd->wpa_auth->wpa_ie_len;
|
||||
return hapd->wpa_auth->wpa_ie;
|
||||
}
|
||||
|
||||
bool wpa_ap_rx_eapol(void *hapd_data, void *sm_data, u8 *data, size_t data_len)
|
||||
{
|
||||
struct hostapd_data *hapd = (struct hostapd_data *)hapd_data;
|
||||
struct wpa_state_machine *sm = (struct wpa_state_machine *)sm_data;
|
||||
|
||||
if (!hapd || !sm) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wpa_receive(hapd->wpa_auth, sm, data, data_len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wpa_deattach(void)
|
||||
{
|
||||
wpa_sm_deinit();
|
||||
return true;
|
||||
}
|
||||
|
||||
void wpa_sta_connect(uint8_t *bssid)
|
||||
{
|
||||
int ret = 0;
|
||||
wpa_config_profile();
|
||||
wpa_config_bss(bssid);
|
||||
ret = wpa_config_bss(bssid);
|
||||
WPA_ASSERT(ret == 0);
|
||||
}
|
||||
|
||||
int wpa_parse_wpa_ie_wrapper(const u8 *wpa_ie, size_t wpa_ie_len, wifi_wpa_ie_t *data)
|
||||
{
|
||||
struct wpa_ie_data ie;
|
||||
int ret = 0;
|
||||
|
||||
ret = wpa_parse_wpa_ie(wpa_ie, wpa_ie_len, &ie);
|
||||
data->proto = ie.proto;
|
||||
data->pairwise_cipher = cipher_type_map_supp_to_public(ie.pairwise_cipher);
|
||||
data->group_cipher = cipher_type_map_supp_to_public(ie.group_cipher);
|
||||
data->key_mgmt = ie.key_mgmt;
|
||||
data->capabilities = ie.capabilities;
|
||||
data->pmkid = ie.pmkid;
|
||||
data->mgmt_group_cipher = cipher_type_map_supp_to_public(ie.mgmt_group_cipher);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wpa_sta_disconnected_cb(uint8_t reason_code)
|
||||
{
|
||||
switch (reason_code) {
|
||||
case WIFI_REASON_UNSPECIFIED:
|
||||
case WIFI_REASON_AUTH_EXPIRE:
|
||||
case WIFI_REASON_NOT_AUTHED:
|
||||
case WIFI_REASON_NOT_ASSOCED:
|
||||
case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT:
|
||||
case WIFI_REASON_INVALID_PMKID:
|
||||
case WIFI_REASON_AUTH_FAIL:
|
||||
case WIFI_REASON_ASSOC_FAIL:
|
||||
case WIFI_REASON_CONNECTION_FAIL:
|
||||
case WIFI_REASON_HANDSHAKE_TIMEOUT:
|
||||
esp_wpa3_free_sae_data();
|
||||
wpa_sta_clear_curr_pmksa();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int esp_supplicant_init(void)
|
||||
{
|
||||
struct wpa_funcs *wpa_cb;
|
||||
|
||||
wpa_cb = (struct wpa_funcs *)os_malloc(sizeof(struct wpa_funcs));
|
||||
if (!wpa_cb) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
wpa_cb->wpa_sta_init = wpa_attach;
|
||||
wpa_cb->wpa_sta_deinit = wpa_deattach;
|
||||
wpa_cb->wpa_sta_rx_eapol = wpa_sm_rx_eapol;
|
||||
wpa_cb->wpa_sta_connect = wpa_sta_connect;
|
||||
wpa_cb->wpa_sta_disconnected_cb = wpa_sta_disconnected_cb;
|
||||
wpa_cb->wpa_sta_in_4way_handshake = wpa_sta_in_4way_handshake;
|
||||
|
||||
wpa_cb->wpa_ap_join = wpa_ap_join;
|
||||
wpa_cb->wpa_ap_remove = wpa_ap_remove;
|
||||
wpa_cb->wpa_ap_get_wpa_ie = wpa_ap_get_wpa_ie;
|
||||
wpa_cb->wpa_ap_rx_eapol = wpa_ap_rx_eapol;
|
||||
wpa_cb->wpa_ap_init = hostap_init;
|
||||
wpa_cb->wpa_ap_deinit = hostap_deinit;
|
||||
|
||||
wpa_cb->wpa_config_parse_string = wpa_config_parse_string;
|
||||
wpa_cb->wpa_parse_wpa_ie = wpa_parse_wpa_ie_wrapper;
|
||||
wpa_cb->wpa_config_bss = NULL;//wpa_config_bss;
|
||||
wpa_cb->wpa_michael_mic_failure = wpa_michael_mic_failure;
|
||||
esp_wifi_register_wpa3_cb(wpa_cb);
|
||||
|
||||
esp_wifi_register_wpa_cb_internal(wpa_cb);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int esp_supplicant_deinit(void)
|
||||
{
|
||||
return esp_wifi_unregister_wpa_cb_internal();
|
||||
}
|
||||
|
@ -19,10 +19,6 @@
|
||||
#include "common/eapol_common.h"
|
||||
#include "rsn_supp/wpa.h"
|
||||
#include "rsn_supp/pmksa_cache.h"
|
||||
#define EP_OFFSET 36
|
||||
|
||||
#define wpa_malloc_dram(s) heap_caps_malloc(s, MALLOC_CAP_8BIT)
|
||||
#define wpa_calloc_dram(n, s) heap_caps_calloc(n, s, MALLOC_CAP_8BIT)
|
||||
|
||||
u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type,
|
||||
const void *data, u16 data_len,
|
||||
@ -33,14 +29,12 @@ u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type,
|
||||
|
||||
*msg_len = sizeof(struct ieee802_1x_hdr) + data_len;
|
||||
|
||||
buffer = wpa_malloc_dram(*msg_len + sizeof(struct l2_ethhdr) + EP_OFFSET);
|
||||
buffer = os_malloc(*msg_len + sizeof(struct l2_ethhdr));
|
||||
|
||||
if (buffer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer += EP_OFFSET;
|
||||
|
||||
/* XXX: reserve l2_ethhdr is enough */
|
||||
hdr = (struct ieee802_1x_hdr *)((char *)buffer + sizeof(struct l2_ethhdr));
|
||||
|
||||
@ -63,8 +57,8 @@ u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type,
|
||||
|
||||
void wpa_sm_free_eapol(u8 *buffer)
|
||||
{
|
||||
// buffer = buffer - sizeof(struct l2_ethhdr) - EP_OFFSET;
|
||||
// os_free(buffer);
|
||||
buffer = buffer - sizeof(struct l2_ethhdr);
|
||||
os_free(buffer);
|
||||
}
|
||||
|
||||
void wpa_sm_deauthenticate(struct wpa_sm *sm, u8 reason_code)
|
||||
|
2196
components/wpa_supplicant/src/esp_supplicant/esp_wps.c
Executable file
2196
components/wpa_supplicant/src/esp_supplicant/esp_wps.c
Executable file
File diff suppressed because it is too large
Load Diff
@ -1,82 +0,0 @@
|
||||
// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "crypto/aes.h"
|
||||
#include "crypto/aes_wrap.h"
|
||||
|
||||
#if CONFIG_SSL_USING_MBEDTLS
|
||||
#include "mbedtls/aes.h"
|
||||
|
||||
/**
|
||||
* fast_aes_128_cbc_encrypt - AES-128 CBC encryption
|
||||
* @key: Encryption key
|
||||
* @iv: Encryption IV for CBC mode (16 bytes)
|
||||
* @data: Data to encrypt in-place
|
||||
* @data_len: Length of data in bytes (must be divisible by 16)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int
|
||||
fast_aes_128_cbc_encrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data, size_t data_len)
|
||||
{
|
||||
int ret = 0;
|
||||
mbedtls_aes_context ctx;
|
||||
uint8_t cbc[AES_BLOCK_SIZE];
|
||||
|
||||
mbedtls_aes_init(&ctx);
|
||||
|
||||
ret = mbedtls_aes_setkey_enc(&ctx, key, 128);
|
||||
|
||||
if(ret < 0) {
|
||||
mbedtls_aes_free(&ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
os_memcpy(cbc, iv, AES_BLOCK_SIZE);
|
||||
|
||||
ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, data_len, cbc, data, data);
|
||||
|
||||
mbedtls_aes_free(&ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* fast_aes_128_cbc_decrypt - AES-128 CBC decryption
|
||||
* @key: Decryption key
|
||||
* @iv: Decryption IV for CBC mode (16 bytes)
|
||||
* @data: Data to decrypt in-place
|
||||
* @data_len: Length of data in bytes (must be divisible by 16)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int
|
||||
fast_aes_128_cbc_decrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data, size_t data_len)
|
||||
{
|
||||
int ret = 0;
|
||||
mbedtls_aes_context ctx;
|
||||
uint8_t cbc[AES_BLOCK_SIZE];
|
||||
|
||||
mbedtls_aes_init(&ctx);
|
||||
|
||||
ret = mbedtls_aes_setkey_dec(&ctx, key, 128);
|
||||
|
||||
if(ret < 0) {
|
||||
mbedtls_aes_free(&ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
os_memcpy(cbc, iv, AES_BLOCK_SIZE);
|
||||
|
||||
ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, data_len, cbc, data, data);
|
||||
|
||||
mbedtls_aes_free(&ctx);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
#endif
|
@ -1,87 +0,0 @@
|
||||
// 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
|
||||
//
|
||||
// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// 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.
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
|
||||
#if CONFIG_SSL_USING_MBEDTLS
|
||||
#include "mbedtls/aes.h"
|
||||
/**
|
||||
* fast_aes_unwrap - Unwrap key with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
|
||||
* @kek: Key encryption key (KEK)
|
||||
* @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
|
||||
* bytes
|
||||
* @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bits
|
||||
* @plain: Plaintext key, n * 64 bits
|
||||
* Returns: 0 on success, -1 on failure (e.g., integrity verification failed)
|
||||
*/
|
||||
int
|
||||
fast_aes_unwrap(const uint8_t *kek, int n, const uint8_t *cipher, uint8_t *plain)
|
||||
{
|
||||
uint8_t a[8], *r, b[16];
|
||||
int32_t i, j;
|
||||
int32_t ret = 0;
|
||||
mbedtls_aes_context ctx;
|
||||
|
||||
/* 1) Initialize variables. */
|
||||
os_memcpy(a, cipher, 8);
|
||||
r = plain;
|
||||
os_memcpy(r, cipher + 8, 8 * n);
|
||||
|
||||
mbedtls_aes_init(&ctx);
|
||||
ret = mbedtls_aes_setkey_dec(&ctx, kek, 128);
|
||||
if (ret < 0) {
|
||||
mbedtls_aes_free(&ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 2) Compute intermediate values.
|
||||
* For j = 5 to 0
|
||||
* For i = n to 1
|
||||
* B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
|
||||
* A = MSB(64, B)
|
||||
* R[i] = LSB(64, B)
|
||||
*/
|
||||
for (j = 5; j >= 0; j--) {
|
||||
r = plain + (n - 1) * 8;
|
||||
for (i = n; i >= 1; i--) {
|
||||
os_memcpy(b, a, 8);
|
||||
b[7] ^= n * j + i;
|
||||
os_memcpy(b + 8, r, 8);
|
||||
ret = mbedtls_internal_aes_decrypt(&ctx, b, b);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
os_memcpy(a, b, 8);
|
||||
os_memcpy(r, b + 8, 8);
|
||||
r -= 8;
|
||||
}
|
||||
}
|
||||
mbedtls_aes_free(&ctx);
|
||||
|
||||
/* 3) Output results.
|
||||
*
|
||||
* These are already in @plain due to the location of temporary
|
||||
* variables. Just verify that the IV matches with the expected value.
|
||||
*/
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (a[i] != 0xa6) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
@ -1,88 +0,0 @@
|
||||
// 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
|
||||
//
|
||||
// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "crypto/aes.h"
|
||||
#include "crypto/aes_wrap.h"
|
||||
|
||||
#if CONFIG_SSL_USING_MBEDTLS
|
||||
#include "mbedtls/aes.h"
|
||||
|
||||
/**
|
||||
* fast_aes_wrap - Wrap keys with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
|
||||
* @kek: 16-octet Key encryption key (KEK)
|
||||
* @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
|
||||
* bytes
|
||||
* @plain: Plaintext key to be wrapped, n * 64 bits
|
||||
* @cipher: Wrapped key, (n + 1) * 64 bits
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int fast_aes_wrap(const uint8_t *kek, int n, const uint8_t *plain, uint8_t *cipher)
|
||||
{
|
||||
uint8_t *a, *r, b[16];
|
||||
int32_t i, j;
|
||||
int32_t ret = 0;
|
||||
mbedtls_aes_context ctx;
|
||||
|
||||
a = cipher;
|
||||
r = cipher + 8;
|
||||
|
||||
/* 1) Initialize variables. */
|
||||
os_memset(a, 0xa6, 8);
|
||||
os_memcpy(r, plain, 8 * n);
|
||||
|
||||
mbedtls_aes_init(&ctx);
|
||||
ret = mbedtls_aes_setkey_enc(&ctx, kek, 128);
|
||||
if (ret < 0) {
|
||||
mbedtls_aes_free(&ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 2) Calculate intermediate values.
|
||||
* For j = 0 to 5
|
||||
* For i=1 to n
|
||||
* B = AES(K, A | R[i])
|
||||
* A = MSB(64, B) ^ t where t = (n*j)+i
|
||||
* R[i] = LSB(64, B)
|
||||
*/
|
||||
for (j = 0; j <= 5; j++) {
|
||||
r = cipher + 8;
|
||||
for (i = 1; i <= n; i++) {
|
||||
os_memcpy(b, a, 8);
|
||||
os_memcpy(b + 8, r, 8);
|
||||
ret = mbedtls_internal_aes_encrypt(&ctx, b, b);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
os_memcpy(a, b, 8);
|
||||
a[7] ^= n * j + i;
|
||||
os_memcpy(r, b + 8, 8);
|
||||
r += 8;
|
||||
}
|
||||
}
|
||||
mbedtls_aes_free(&ctx);
|
||||
|
||||
/* 3) Output the results.
|
||||
*
|
||||
* These are already in @cipher due to the location of temporary
|
||||
* variables.
|
||||
*/
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
@ -1,290 +0,0 @@
|
||||
// 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
|
||||
//
|
||||
// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// 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.
|
||||
|
||||
//#include "utils/includes.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/aes.h"
|
||||
#if defined(CONFIG_DES) || defined(CONFIG_DES3)
|
||||
#include "crypto/des_i.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_SSL_USING_MBEDTLS
|
||||
#include "mbedtls/aes.h"
|
||||
|
||||
struct fast_crypto_cipher {
|
||||
enum crypto_cipher_alg alg;
|
||||
union {
|
||||
struct {
|
||||
size_t used_bytes;
|
||||
uint8_t key[16];
|
||||
size_t keylen;
|
||||
} rc4;
|
||||
struct {
|
||||
uint8_t cbc[32];
|
||||
mbedtls_aes_context ctx_enc;
|
||||
mbedtls_aes_context ctx_dec;
|
||||
} aes;
|
||||
#ifdef CONFIG_DES3
|
||||
struct {
|
||||
struct des3_key_s key;
|
||||
uint8_t cbc[8];
|
||||
} des3;
|
||||
#endif
|
||||
#ifdef CONFIG_DES
|
||||
struct {
|
||||
uint32_t ek[32];
|
||||
uint32_t dk[32];
|
||||
uint32_t cbc[8];
|
||||
} des;
|
||||
#endif
|
||||
} u;
|
||||
};
|
||||
|
||||
|
||||
struct crypto_cipher * fast_crypto_cipher_init(enum crypto_cipher_alg alg,
|
||||
const uint8_t *iv, const uint8_t *key,
|
||||
size_t key_len)
|
||||
{
|
||||
struct fast_crypto_cipher *ctx;
|
||||
|
||||
ctx = (struct fast_crypto_cipher *)os_zalloc(sizeof(*ctx));
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->alg = alg;
|
||||
|
||||
switch (alg) {
|
||||
case CRYPTO_CIPHER_ALG_RC4:
|
||||
if (key_len > sizeof(ctx->u.rc4.key)) {
|
||||
os_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
ctx->u.rc4.keylen = key_len;
|
||||
os_memcpy(ctx->u.rc4.key, key, key_len);
|
||||
break;
|
||||
case CRYPTO_CIPHER_ALG_AES:
|
||||
mbedtls_aes_init(&(ctx->u.aes.ctx_enc));
|
||||
mbedtls_aes_setkey_enc(&(ctx->u.aes.ctx_enc), key, key_len * 8);
|
||||
mbedtls_aes_init(&(ctx->u.aes.ctx_dec));
|
||||
mbedtls_aes_setkey_dec(&(ctx->u.aes.ctx_dec), key, key_len * 8);
|
||||
os_memcpy(ctx->u.aes.cbc, iv, AES_BLOCK_SIZE);
|
||||
break;
|
||||
#ifdef CONFIG_DES3
|
||||
case CRYPTO_CIPHER_ALG_3DES:
|
||||
if (key_len != 24) {
|
||||
os_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
des3_key_setup(key, &ctx->u.des3.key);
|
||||
os_memcpy(ctx->u.des3.cbc, iv, 8);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_DES
|
||||
case CRYPTO_CIPHER_ALG_DES:
|
||||
if (key_len != 8) {
|
||||
os_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
des_key_setup(key, ctx->u.des.ek, ctx->u.des.dk);
|
||||
os_memcpy(ctx->u.des.cbc, iv, 8);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
os_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (struct crypto_cipher *)ctx;
|
||||
}
|
||||
|
||||
|
||||
int fast_crypto_cipher_encrypt(struct crypto_cipher *ctx, const uint8_t *plain,
|
||||
uint8_t *crypt, size_t len)
|
||||
{
|
||||
size_t i, j, blocks;
|
||||
struct fast_crypto_cipher *fast_ctx;
|
||||
|
||||
fast_ctx = (struct fast_crypto_cipher *)ctx;
|
||||
|
||||
switch (fast_ctx->alg) {
|
||||
case CRYPTO_CIPHER_ALG_RC4:
|
||||
if (plain != crypt) {
|
||||
os_memcpy(crypt, plain, len);
|
||||
}
|
||||
rc4_skip(fast_ctx->u.rc4.key, fast_ctx->u.rc4.keylen,
|
||||
fast_ctx->u.rc4.used_bytes, crypt, len);
|
||||
fast_ctx->u.rc4.used_bytes += len;
|
||||
break;
|
||||
case CRYPTO_CIPHER_ALG_AES:
|
||||
if (len % AES_BLOCK_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
blocks = len / AES_BLOCK_SIZE;
|
||||
for (i = 0; i < blocks; i++) {
|
||||
for (j = 0; j < AES_BLOCK_SIZE; j++)
|
||||
fast_ctx->u.aes.cbc[j] ^= plain[j];
|
||||
if (mbedtls_internal_aes_encrypt(&(fast_ctx->u.aes.ctx_enc), fast_ctx->u.aes.cbc, fast_ctx->u.aes.cbc) != 0) {
|
||||
return -1;
|
||||
}
|
||||
os_memcpy(crypt, fast_ctx->u.aes.cbc, AES_BLOCK_SIZE);
|
||||
plain += AES_BLOCK_SIZE;
|
||||
crypt += AES_BLOCK_SIZE;
|
||||
}
|
||||
break;
|
||||
#ifdef CONFIG_DES3
|
||||
case CRYPTO_CIPHER_ALG_3DES:
|
||||
if (len % 8) {
|
||||
return -1;
|
||||
}
|
||||
blocks = len / 8;
|
||||
for (i = 0; i < blocks; i++) {
|
||||
for (j = 0; j < 8; j++)
|
||||
fast_ctx->u.des3.cbc[j] ^= plain[j];
|
||||
des3_encrypt(fast_ctx->u.des3.cbc, &fast_ctx->u.des3.key,
|
||||
fast_ctx->u.des3.cbc);
|
||||
os_memcpy(crypt, fast_ctx->u.des3.cbc, 8);
|
||||
plain += 8;
|
||||
crypt += 8;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_DES
|
||||
case CRYPTO_CIPHER_ALG_DES:
|
||||
if (len % 8) {
|
||||
return -1;
|
||||
}
|
||||
blocks = len / 8;
|
||||
for (i = 0; i < blocks; i++) {
|
||||
for (j = 0; j < 8; j++)
|
||||
fast_ctx->u.des3.cbc[j] ^= plain[j];
|
||||
des_block_encrypt(fast_ctx->u.des.cbc, fast_ctx->u.des.ek,
|
||||
fast_ctx->u.des.cbc);
|
||||
os_memcpy(crypt, fast_ctx->u.des.cbc, 8);
|
||||
plain += 8;
|
||||
crypt += 8;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int fast_crypto_cipher_decrypt(struct crypto_cipher *ctx, const uint8_t *crypt,
|
||||
uint8_t *plain, size_t len)
|
||||
{
|
||||
size_t i, j, blocks;
|
||||
uint8_t tmp[32];
|
||||
struct fast_crypto_cipher *fast_ctx;
|
||||
|
||||
fast_ctx = (struct fast_crypto_cipher *)ctx;
|
||||
|
||||
switch (fast_ctx->alg) {
|
||||
case CRYPTO_CIPHER_ALG_RC4:
|
||||
if (plain != crypt) {
|
||||
os_memcpy(plain, crypt, len);
|
||||
}
|
||||
rc4_skip(fast_ctx->u.rc4.key, fast_ctx->u.rc4.keylen,
|
||||
fast_ctx->u.rc4.used_bytes, plain, len);
|
||||
fast_ctx->u.rc4.used_bytes += len;
|
||||
break;
|
||||
case CRYPTO_CIPHER_ALG_AES:
|
||||
if (len % AES_BLOCK_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
blocks = len / AES_BLOCK_SIZE;
|
||||
for (i = 0; i < blocks; i++) {
|
||||
os_memcpy(tmp, crypt, AES_BLOCK_SIZE);
|
||||
if (mbedtls_internal_aes_decrypt(&(fast_ctx->u.aes.ctx_dec), crypt, plain) != 0) {
|
||||
return -1;
|
||||
}
|
||||
for (j = 0; j < AES_BLOCK_SIZE; j++)
|
||||
plain[j] ^= fast_ctx->u.aes.cbc[j];
|
||||
os_memcpy(fast_ctx->u.aes.cbc, tmp, AES_BLOCK_SIZE);
|
||||
plain += AES_BLOCK_SIZE;
|
||||
crypt += AES_BLOCK_SIZE;
|
||||
}
|
||||
break;
|
||||
#ifdef CONFIG_DES3
|
||||
case CRYPTO_CIPHER_ALG_3DES:
|
||||
if (len % 8) {
|
||||
return -1;
|
||||
}
|
||||
blocks = len / 8;
|
||||
for (i = 0; i < blocks; i++) {
|
||||
os_memcpy(tmp, crypt, 8);
|
||||
des3_decrypt(crypt, &fast_ctx->u.des3.key, plain);
|
||||
for (j = 0; j < 8; j++) {
|
||||
plain[j] ^= fast_ctx->u.des3.cbc[j];
|
||||
}
|
||||
os_memcpy(fast_ctx->u.des3.cbc, tmp, 8);
|
||||
plain += 8;
|
||||
crypt += 8;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_DES
|
||||
case CRYPTO_CIPHER_ALG_DES:
|
||||
if (len % 8) {
|
||||
return -1;
|
||||
}
|
||||
blocks = len / 8;
|
||||
for (i = 0; i < blocks; i++) {
|
||||
os_memcpy(tmp, crypt, 8);
|
||||
des_block_decrypt(crypt, fast_ctx->u.des.dk, plain);
|
||||
for (j = 0; j < 8; j++) {
|
||||
plain[j] ^= fast_ctx->u.des.cbc[j];
|
||||
}
|
||||
os_memcpy(fast_ctx->u.des.cbc, tmp, 8);
|
||||
plain += 8;
|
||||
crypt += 8;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void fast_crypto_cipher_deinit(struct crypto_cipher *ctx)
|
||||
{
|
||||
struct fast_crypto_cipher *fast_ctx;
|
||||
|
||||
fast_ctx = (struct fast_crypto_cipher *)ctx;
|
||||
|
||||
switch (fast_ctx->alg) {
|
||||
case CRYPTO_CIPHER_ALG_AES:
|
||||
mbedtls_aes_free(&(fast_ctx->u.aes.ctx_enc));
|
||||
mbedtls_aes_free(&(fast_ctx->u.aes.ctx_dec));
|
||||
break;
|
||||
#ifdef CONFIG_DES3
|
||||
case CRYPTO_CIPHER_ALG_3DES:
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
os_free(ctx);
|
||||
}
|
||||
#endif
|
@ -1,64 +0,0 @@
|
||||
// Hardware crypto support Copyright 2017 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.
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "crypto/crypto.h"
|
||||
|
||||
#if CONFIG_SSL_USING_MBEDTLS
|
||||
#include "mbedtls/bignum.h"
|
||||
|
||||
int fast_crypto_mod_exp(const uint8_t *base, size_t base_len,
|
||||
const uint8_t *power, size_t power_len,
|
||||
const uint8_t *modulus, size_t modulus_len,
|
||||
uint8_t *result, size_t *result_len)
|
||||
{
|
||||
mbedtls_mpi bn_base, bn_exp, bn_modulus, bn_result, bn_rinv;
|
||||
int32_t ret = 0;
|
||||
mbedtls_mpi_init(&bn_base);
|
||||
mbedtls_mpi_init(&bn_exp);
|
||||
mbedtls_mpi_init(&bn_modulus);
|
||||
mbedtls_mpi_init(&bn_result);
|
||||
mbedtls_mpi_init(&bn_rinv);
|
||||
|
||||
mbedtls_mpi_read_binary(&bn_base, base, base_len);
|
||||
mbedtls_mpi_read_binary(&bn_exp, power, power_len);
|
||||
mbedtls_mpi_read_binary(&bn_modulus, modulus, modulus_len);
|
||||
|
||||
ret = mbedtls_mpi_exp_mod(&bn_result, &bn_base, &bn_exp, &bn_modulus, &bn_rinv);
|
||||
|
||||
if (ret < 0) {
|
||||
mbedtls_mpi_free(&bn_base);
|
||||
mbedtls_mpi_free(&bn_exp);
|
||||
mbedtls_mpi_free(&bn_modulus);
|
||||
mbedtls_mpi_free(&bn_result);
|
||||
mbedtls_mpi_free(&bn_rinv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_write_binary(&bn_result, result, *result_len);
|
||||
|
||||
|
||||
mbedtls_mpi_free(&bn_base);
|
||||
mbedtls_mpi_free(&bn_exp);
|
||||
mbedtls_mpi_free(&bn_modulus);
|
||||
mbedtls_mpi_free(&bn_result);
|
||||
mbedtls_mpi_free(&bn_rinv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
@ -1,289 +0,0 @@
|
||||
/*
|
||||
* Crypto wrapper for internal crypto implementation
|
||||
* Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/sha1_i.h"
|
||||
#include "crypto/md5_i.h"
|
||||
|
||||
#if CONFIG_SSL_USING_MBEDTLS
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
|
||||
#ifdef MEMLEAK_DEBUG
|
||||
static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
|
||||
#endif
|
||||
|
||||
struct fast_crypto_hash {
|
||||
enum crypto_hash_alg alg;
|
||||
union {
|
||||
struct MD5Context md5;
|
||||
#ifndef CONFIG_ESP_SHA
|
||||
struct SHA1Context sha1;
|
||||
#else
|
||||
SHA1_CTX sha1;
|
||||
#endif
|
||||
#ifdef CONFIG_SHA256
|
||||
mbedtls_sha256_context sha256;
|
||||
#endif /* CONFIG_SHA256 */
|
||||
} u;
|
||||
u8 key[64];
|
||||
size_t key_len;
|
||||
};
|
||||
|
||||
struct crypto_hash* fast_crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
|
||||
size_t key_len)
|
||||
{
|
||||
struct fast_crypto_hash *ctx;
|
||||
u8 k_pad[64];
|
||||
u8 tk[32];
|
||||
size_t i;
|
||||
|
||||
ctx = (struct fast_crypto_hash *)os_zalloc(sizeof(*ctx));
|
||||
if (ctx == NULL)
|
||||
return NULL;
|
||||
|
||||
ctx->alg = alg;
|
||||
|
||||
switch (alg) {
|
||||
case CRYPTO_HASH_ALG_MD5:
|
||||
MD5Init(&ctx->u.md5);
|
||||
break;
|
||||
case CRYPTO_HASH_ALG_SHA1:
|
||||
SHA1Init(&ctx->u.sha1);
|
||||
break;
|
||||
#ifdef CONFIG_SHA256
|
||||
case CRYPTO_HASH_ALG_SHA256:
|
||||
mbedtls_sha256_init(&ctx->u.sha256);
|
||||
mbedtls_sha256_starts(&ctx->u.sha256, 0);
|
||||
break;
|
||||
#endif /* CONFIG_SHA256 */
|
||||
case CRYPTO_HASH_ALG_HMAC_MD5:
|
||||
if (key_len > sizeof(k_pad)) {
|
||||
MD5Init(&ctx->u.md5);
|
||||
MD5Update(&ctx->u.md5, key, key_len);
|
||||
MD5Final(tk, &ctx->u.md5);
|
||||
key = tk;
|
||||
key_len = 16;
|
||||
}
|
||||
os_memcpy(ctx->key, key, key_len);
|
||||
ctx->key_len = key_len;
|
||||
|
||||
os_memcpy(k_pad, key, key_len);
|
||||
if (key_len < sizeof(k_pad))
|
||||
os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
|
||||
for (i = 0; i < sizeof(k_pad); i++)
|
||||
k_pad[i] ^= 0x36;
|
||||
MD5Init(&ctx->u.md5);
|
||||
MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
|
||||
break;
|
||||
case CRYPTO_HASH_ALG_HMAC_SHA1:
|
||||
if (key_len > sizeof(k_pad)) {
|
||||
SHA1Init(&ctx->u.sha1);
|
||||
SHA1Update(&ctx->u.sha1, key, key_len);
|
||||
SHA1Final(tk, &ctx->u.sha1);
|
||||
key = tk;
|
||||
key_len = 20;
|
||||
}
|
||||
os_memcpy(ctx->key, key, key_len);
|
||||
ctx->key_len = key_len;
|
||||
|
||||
os_memcpy(k_pad, key, key_len);
|
||||
if (key_len < sizeof(k_pad))
|
||||
os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
|
||||
for (i = 0; i < sizeof(k_pad); i++)
|
||||
k_pad[i] ^= 0x36;
|
||||
SHA1Init(&ctx->u.sha1);
|
||||
SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
|
||||
break;
|
||||
#ifdef CONFIG_SHA256
|
||||
case CRYPTO_HASH_ALG_HMAC_SHA256:
|
||||
if (key_len > sizeof(k_pad)) {
|
||||
mbedtls_sha256_init(&ctx->u.sha256);
|
||||
mbedtls_sha256_starts(&ctx->u.sha256, 0);
|
||||
mbedtls_sha256_update(&ctx->u.sha256, key, key_len);
|
||||
mbedtls_sha256_finish(&ctx->u.sha256, tk);
|
||||
mbedtls_sha256_free(&ctx->u.sha256);
|
||||
key = tk;
|
||||
key_len = 32;
|
||||
}
|
||||
os_memcpy(ctx->key, key, key_len);
|
||||
ctx->key_len = key_len;
|
||||
|
||||
os_memcpy(k_pad, key, key_len);
|
||||
if (key_len < sizeof(k_pad))
|
||||
os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
|
||||
for (i = 0; i < sizeof(k_pad); i++)
|
||||
k_pad[i] ^= 0x36;
|
||||
mbedtls_sha256_init(&ctx->u.sha256);
|
||||
mbedtls_sha256_starts(&ctx->u.sha256, 0);
|
||||
mbedtls_sha256_update(&ctx->u.sha256, k_pad, sizeof(k_pad));
|
||||
break;
|
||||
#endif /* CONFIG_SHA256 */
|
||||
default:
|
||||
os_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (struct crypto_hash *)ctx;
|
||||
}
|
||||
|
||||
|
||||
void fast_crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
|
||||
{
|
||||
|
||||
struct fast_crypto_hash *fast_ctx;
|
||||
fast_ctx = (struct fast_crypto_hash *)ctx;
|
||||
|
||||
if (fast_ctx == NULL)
|
||||
return;
|
||||
|
||||
switch (fast_ctx->alg) {
|
||||
case CRYPTO_HASH_ALG_MD5:
|
||||
case CRYPTO_HASH_ALG_HMAC_MD5:
|
||||
MD5Update(&fast_ctx->u.md5, data, len);
|
||||
break;
|
||||
case CRYPTO_HASH_ALG_SHA1:
|
||||
case CRYPTO_HASH_ALG_HMAC_SHA1:
|
||||
SHA1Update(&fast_ctx->u.sha1, data, len);
|
||||
break;
|
||||
#ifdef CONFIG_SHA256
|
||||
case CRYPTO_HASH_ALG_SHA256:
|
||||
case CRYPTO_HASH_ALG_HMAC_SHA256:
|
||||
mbedtls_sha256_update(&fast_ctx->u.sha256, data, len);
|
||||
break;
|
||||
#endif /* CONFIG_SHA256 */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int fast_crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
|
||||
{
|
||||
u8 k_pad[64];
|
||||
size_t i;
|
||||
struct fast_crypto_hash *fast_ctx;
|
||||
|
||||
if (ctx == NULL)
|
||||
return -2;
|
||||
|
||||
fast_ctx = (struct fast_crypto_hash *)ctx;
|
||||
|
||||
if (mac == NULL || len == NULL) {
|
||||
os_free(fast_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (fast_ctx->alg) {
|
||||
case CRYPTO_HASH_ALG_MD5:
|
||||
if (*len < 16) {
|
||||
*len = 16;
|
||||
os_free(fast_ctx);
|
||||
return -1;
|
||||
}
|
||||
*len = 16;
|
||||
MD5Final(mac, &fast_ctx->u.md5);
|
||||
break;
|
||||
case CRYPTO_HASH_ALG_SHA1:
|
||||
if (*len < 20) {
|
||||
*len = 20;
|
||||
os_free(fast_ctx);
|
||||
return -1;
|
||||
}
|
||||
*len = 20;
|
||||
SHA1Final(mac, &fast_ctx->u.sha1);
|
||||
break;
|
||||
#ifdef CONFIG_SHA256
|
||||
case CRYPTO_HASH_ALG_SHA256:
|
||||
if (*len < 32) {
|
||||
*len = 32;
|
||||
os_free(fast_ctx);
|
||||
return -1;
|
||||
}
|
||||
*len = 32;
|
||||
mbedtls_sha256_finish(&fast_ctx->u.sha256, mac);
|
||||
mbedtls_sha256_free(&fast_ctx->u.sha256);
|
||||
break;
|
||||
#endif /* CONFIG_SHA256 */
|
||||
case CRYPTO_HASH_ALG_HMAC_MD5:
|
||||
if (*len < 16) {
|
||||
*len = 16;
|
||||
os_free(fast_ctx);
|
||||
return -1;
|
||||
}
|
||||
*len = 16;
|
||||
|
||||
MD5Final(mac, &fast_ctx->u.md5);
|
||||
|
||||
os_memcpy(k_pad, fast_ctx->key, fast_ctx->key_len);
|
||||
os_memset(k_pad + fast_ctx->key_len, 0,
|
||||
sizeof(k_pad) - fast_ctx->key_len);
|
||||
for (i = 0; i < sizeof(k_pad); i++)
|
||||
k_pad[i] ^= 0x5c;
|
||||
MD5Init(&fast_ctx->u.md5);
|
||||
MD5Update(&fast_ctx->u.md5, k_pad, sizeof(k_pad));
|
||||
MD5Update(&fast_ctx->u.md5, mac, 16);
|
||||
MD5Final(mac, &fast_ctx->u.md5);
|
||||
break;
|
||||
case CRYPTO_HASH_ALG_HMAC_SHA1:
|
||||
if (*len < 20) {
|
||||
*len = 20;
|
||||
os_free(ctx);
|
||||
return -1;
|
||||
}
|
||||
*len = 20;
|
||||
|
||||
SHA1Final(mac, &fast_ctx->u.sha1);
|
||||
os_memcpy(k_pad, fast_ctx->key, fast_ctx->key_len);
|
||||
os_memset(k_pad + fast_ctx->key_len, 0,
|
||||
sizeof(k_pad) - fast_ctx->key_len);
|
||||
for (i = 0; i < sizeof(k_pad); i++)
|
||||
k_pad[i] ^= 0x5c;
|
||||
SHA1Init(&fast_ctx->u.sha1);
|
||||
SHA1Update(&fast_ctx->u.sha1, k_pad, sizeof(k_pad));
|
||||
SHA1Update(&fast_ctx->u.sha1, mac, 20);
|
||||
SHA1Final(mac, &fast_ctx->u.sha1);
|
||||
break;
|
||||
#ifdef CONFIG_SHA256
|
||||
case CRYPTO_HASH_ALG_HMAC_SHA256:
|
||||
if (*len < 32) {
|
||||
*len = 32;
|
||||
os_free(fast_ctx);
|
||||
return -1;
|
||||
}
|
||||
*len = 32;
|
||||
mbedtls_sha256_finish(&fast_ctx->u.sha256, mac);
|
||||
mbedtls_sha256_free(&fast_ctx->u.sha256);
|
||||
|
||||
os_memcpy(k_pad, fast_ctx->key, fast_ctx->key_len);
|
||||
os_memset(k_pad + fast_ctx->key_len, 0,
|
||||
sizeof(k_pad) - fast_ctx->key_len);
|
||||
for (i = 0; i < sizeof(k_pad); i++)
|
||||
k_pad[i] ^= 0x5c;
|
||||
mbedtls_sha256_init(&fast_ctx->u.sha256);
|
||||
mbedtls_sha256_starts(&fast_ctx->u.sha256, 0);
|
||||
mbedtls_sha256_update(&fast_ctx->u.sha256, k_pad, sizeof(k_pad));
|
||||
mbedtls_sha256_update(&fast_ctx->u.sha256, mac, 32);
|
||||
mbedtls_sha256_finish(&fast_ctx->u.sha256, mac);
|
||||
mbedtls_sha256_free(&fast_ctx->u.sha256);
|
||||
break;
|
||||
#endif /* CONFIG_SHA256 */
|
||||
default:
|
||||
os_free(fast_ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_free(fast_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
@ -1,253 +0,0 @@
|
||||
// Copyright 2015-2017 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.
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "crypto/aes_wrap.h"
|
||||
#include "crypto/sha256.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/md5.h"
|
||||
#include "crypto/sha1.h"
|
||||
#include "crypto/aes.h"
|
||||
#include "crypto/dh_group5.h"
|
||||
#include "wps/wps.h"
|
||||
#include "wps/wps_i.h"
|
||||
|
||||
#include "eap_peer/eap.h"
|
||||
#include "tls/tls.h"
|
||||
#include "eap_peer/eap_methods.h"
|
||||
#include "eap_peer/eap_i.h"
|
||||
#include "eap_peer/eap_common.h"
|
||||
#include "esp_wifi_crypto_types.h"
|
||||
|
||||
int fast_sha256_vector(size_t num_elem, const uint8_t *addr[], const size_t *len,
|
||||
uint8_t *mac);
|
||||
int __must_check fast_aes_wrap(const uint8_t *kek, int n, const uint8_t *plain, uint8_t *cipher);
|
||||
int __must_check fast_aes_unwrap(const uint8_t *kek, int n, const uint8_t *cipher, uint8_t *plain);
|
||||
int __must_check fast_aes_128_cbc_encrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data,
|
||||
size_t data_len);
|
||||
int __must_check fast_aes_128_cbc_decrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data,
|
||||
size_t data_len);
|
||||
void fast_hmac_sha256_vector(const uint8_t *key, size_t key_len, size_t num_elem,
|
||||
const uint8_t *addr[], const size_t *len, uint8_t *mac);
|
||||
void fast_hmac_sha256(const uint8_t *key, size_t key_len, const uint8_t *data,
|
||||
size_t data_len, uint8_t *mac);
|
||||
void fast_sha256_prf(const uint8_t *key, size_t key_len, const char *label,
|
||||
const uint8_t *data, size_t data_len, uint8_t *buf, size_t buf_len);
|
||||
int __must_check fast_aes_wrap(const uint8_t *kek, int n, const uint8_t *plain, uint8_t *cipher);
|
||||
int __must_check fast_aes_unwrap(const uint8_t *kek, int n, const uint8_t *cipher, uint8_t *plain);
|
||||
int __must_check fast_aes_128_cbc_encrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data,
|
||||
size_t data_len);
|
||||
int __must_check fast_aes_128_cbc_decrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data,
|
||||
size_t data_len);
|
||||
int __must_check crypto_mod_exp(const u8 *base, size_t base_len,
|
||||
const u8 *power, size_t power_len,
|
||||
const u8 *modulus, size_t modulus_len,
|
||||
u8 *result, size_t *result_len);
|
||||
void fast_crypto_hash_update(struct crypto_hash *ctx, const uint8_t *data, size_t len);
|
||||
int fast_crypto_hash_finish(struct crypto_hash *ctx, uint8_t *hash, size_t *len);
|
||||
struct crypto_cipher * fast_crypto_cipher_init(enum crypto_cipher_alg alg,
|
||||
const uint8_t *iv, const uint8_t *key,
|
||||
size_t key_len);
|
||||
int __must_check fast_crypto_cipher_decrypt(struct crypto_cipher *ctx,
|
||||
const uint8_t *crypt, uint8_t *plain, size_t len);
|
||||
void fast_crypto_cipher_deinit(struct crypto_cipher *ctx);
|
||||
int __must_check fast_crypto_mod_exp(const uint8_t *base, size_t base_len,
|
||||
const uint8_t *power, size_t power_len,
|
||||
const uint8_t *modulus, size_t modulus_len,
|
||||
uint8_t *result, size_t *result_len);
|
||||
struct crypto_hash * fast_crypto_hash_init(enum crypto_hash_alg alg, const uint8_t *key,
|
||||
size_t key_len);
|
||||
int __must_check fast_crypto_cipher_encrypt(struct crypto_cipher *ctx,
|
||||
const uint8_t *plain, uint8_t *crypt, size_t len);
|
||||
|
||||
#if CONFIG_SSL_USING_MBEDTLS
|
||||
/*
|
||||
* The parameters is used to set the cyrpto callback function for station connect when in security mode,
|
||||
* every callback function can register as fast_xxx or normal one, i.e, fast_aes_wrap or aes_wrap, the
|
||||
* difference between them is the normal API is calculate by software, the fast one use the hardware
|
||||
* crypto in it, can be faster than the normal one, so the callback function register in default is which
|
||||
* we recommend, so as the API in WPS default and WPA2 default.
|
||||
*/
|
||||
const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs = {
|
||||
.size = sizeof(wpa_crypto_funcs_t),
|
||||
.version = ESP_WIFI_CRYPTO_VERSION,
|
||||
.aes_wrap = (esp_aes_wrap_t)fast_aes_wrap,
|
||||
.aes_unwrap = (esp_aes_unwrap_t)fast_aes_unwrap,
|
||||
.hmac_sha256_vector = (esp_hmac_sha256_vector_t)fast_hmac_sha256_vector,
|
||||
.sha256_prf = (esp_sha256_prf_t)fast_sha256_prf,
|
||||
.hmac_md5 = (esp_hmac_md5_t)hmac_md5,
|
||||
.hamc_md5_vector = (esp_hmac_md5_vector_t)hmac_md5_vector,
|
||||
.hmac_sha1 = (esp_hmac_sha1_t)hmac_sha1,
|
||||
.hmac_sha1_vector = (esp_hmac_sha1_vector_t)hmac_sha1_vector,
|
||||
.sha1_prf = (esp_sha1_prf_t)sha1_prf,
|
||||
.sha1_vector = (esp_sha1_vector_t)sha1_vector,
|
||||
.pbkdf2_sha1 = (esp_pbkdf2_sha1_t)pbkdf2_sha1,
|
||||
.rc4_skip = (esp_rc4_skip_t)rc4_skip,
|
||||
.md5_vector = (esp_md5_vector_t)md5_vector,
|
||||
.aes_encrypt = (esp_aes_encrypt_t)aes_encrypt,
|
||||
.aes_encrypt_init = (esp_aes_encrypt_init_t)aes_encrypt_init,
|
||||
.aes_encrypt_deinit = (esp_aes_encrypt_deinit_t)aes_encrypt_deinit,
|
||||
.aes_decrypt = (esp_aes_decrypt_t)aes_decrypt,
|
||||
.aes_decrypt_init = (esp_aes_decrypt_init_t)aes_decrypt_init,
|
||||
.aes_decrypt_deinit = (esp_aes_decrypt_deinit_t)aes_decrypt_deinit
|
||||
};
|
||||
|
||||
const wps_crypto_funcs_t g_wifi_default_wps_crypto_funcs = {
|
||||
.size = sizeof(wps_crypto_funcs_t),
|
||||
.version = ESP_WIFI_CRYPTO_VERSION,
|
||||
.aes_128_encrypt = (esp_aes_128_encrypt_t)fast_aes_128_cbc_encrypt,
|
||||
.aes_128_decrypt = (esp_aes_128_decrypt_t)fast_aes_128_cbc_decrypt,
|
||||
.crypto_mod_exp = (esp_crypto_mod_exp_t)fast_crypto_mod_exp,
|
||||
.hmac_sha256 = (esp_hmac_sha256_t)fast_hmac_sha256,
|
||||
.hmac_sha256_vector = (esp_hmac_sha256_vector_t)fast_hmac_sha256_vector,
|
||||
.sha256_vector = (esp_sha256_vector_t)fast_sha256_vector,
|
||||
.uuid_gen_mac_addr = (esp_uuid_gen_mac_addr_t)uuid_gen_mac_addr,
|
||||
.dh5_free = (esp_dh5_free_t)dh5_free,
|
||||
.wps_build_assoc_req_ie = (esp_wps_build_assoc_req_ie_t)wps_build_assoc_req_ie,
|
||||
.wps_build_assoc_resp_ie = (esp_wps_build_assoc_resp_ie_t)wps_build_assoc_resp_ie,
|
||||
.wps_build_probe_req_ie = (esp_wps_build_probe_req_ie_t)wps_build_probe_req_ie,
|
||||
.wps_build_public_key = (esp_wps_build_public_key_t)wps_build_public_key,
|
||||
.wps_enrollee_get_msg = (esp_wps_enrollee_get_msg_t)wps_enrollee_get_msg,
|
||||
.wps_enrollee_process_msg = (esp_wps_enrollee_process_msg_t)wps_enrollee_process_msg,
|
||||
.wps_generate_pin = (esp_wps_generate_pin_t)wps_generate_pin,
|
||||
.wps_is_selected_pin_registrar = (esp_wps_is_selected_pin_registrar_t)wps_is_selected_pin_registrar,
|
||||
.wps_is_selected_pbc_registrar = (esp_wps_is_selected_pbc_registrar_t)wps_is_selected_pbc_registrar,
|
||||
.eap_msg_alloc = (esp_eap_msg_alloc_t)eap_msg_alloc
|
||||
};
|
||||
|
||||
/*
|
||||
* What should notice is that the cyrpto hash type function and crypto cipher type function can not register
|
||||
* as different, i.e, if you use fast_crypto_hash_init, you should use fast_crypto_hash_update and
|
||||
* fast_crypto_hash_finish for finish hash calculate, rather than call crypto_hash_update and
|
||||
* crypto_hash_finish, so do crypto_cipher.
|
||||
*/
|
||||
const wpa2_crypto_funcs_t g_wifi_default_wpa2_crypto_funcs = {
|
||||
.size = sizeof(wpa2_crypto_funcs_t),
|
||||
.version = ESP_WIFI_CRYPTO_VERSION,
|
||||
.crypto_hash_init = (esp_crypto_hash_init_t)fast_crypto_hash_init,
|
||||
.crypto_hash_update = (esp_crypto_hash_update_t)fast_crypto_hash_update,
|
||||
.crypto_hash_finish = (esp_crypto_hash_finish_t)fast_crypto_hash_finish,
|
||||
.crypto_cipher_init = (esp_crypto_cipher_init_t)fast_crypto_cipher_init,
|
||||
.crypto_cipher_encrypt = (esp_crypto_cipher_encrypt_t)fast_crypto_cipher_encrypt,
|
||||
.crypto_cipher_decrypt = (esp_crypto_cipher_decrypt_t)fast_crypto_cipher_decrypt,
|
||||
.crypto_cipher_deinit = (esp_crypto_cipher_deinit_t)fast_crypto_cipher_deinit,
|
||||
.crypto_mod_exp = (esp_crypto_mod_exp_t)crypto_mod_exp,
|
||||
.sha256_vector = (esp_sha256_vector_t)fast_sha256_vector,
|
||||
.tls_init = (esp_tls_init_t)tls_init,
|
||||
.tls_deinit = (esp_tls_deinit_t)tls_deinit,
|
||||
.eap_peer_blob_init = (esp_eap_peer_blob_init_t)eap_peer_blob_init,
|
||||
.eap_peer_blob_deinit = (esp_eap_peer_blob_deinit_t)eap_peer_blob_deinit,
|
||||
.eap_peer_config_init = (esp_eap_peer_config_init_t)eap_peer_config_init,
|
||||
.eap_peer_config_deinit = (esp_eap_peer_config_deinit_t)eap_peer_config_deinit,
|
||||
.eap_peer_register_methods = (esp_eap_peer_register_methods_t)eap_peer_register_methods,
|
||||
.eap_peer_unregister_methods = (esp_eap_peer_unregister_methods_t)eap_peer_unregister_methods,
|
||||
.eap_deinit_prev_method = (esp_eap_deinit_prev_method_t)eap_deinit_prev_method,
|
||||
.eap_peer_get_eap_method = (esp_eap_peer_get_eap_method_t)eap_peer_get_eap_method,
|
||||
.eap_sm_abort = (esp_eap_sm_abort_t)eap_sm_abort,
|
||||
.eap_sm_build_nak = (esp_eap_sm_build_nak_t)eap_sm_build_nak,
|
||||
.eap_sm_build_identity_resp = (esp_eap_sm_build_identity_resp_t)eap_sm_build_identity_resp,
|
||||
.eap_msg_alloc = (esp_eap_msg_alloc_t)eap_msg_alloc
|
||||
};
|
||||
#else
|
||||
|
||||
/*
|
||||
* The parameters is used to set the cyrpto callback function for station connect when in security mode,
|
||||
* every callback function can register as fast_xxx or normal one, i.e, fast_aes_wrap or aes_wrap, the
|
||||
* difference between them is the normal API is calculate by software, the fast one use the hardware
|
||||
* crypto in it, can be faster than the normal one, so the callback function register in default is which
|
||||
* we recommend, so as the API in WPS default and WPA2 default.
|
||||
*/
|
||||
const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs = {
|
||||
.size = sizeof(wpa_crypto_funcs_t),
|
||||
.version = ESP_WIFI_CRYPTO_VERSION,
|
||||
.aes_wrap = (esp_aes_wrap_t)aes_wrap,
|
||||
.aes_unwrap = (esp_aes_unwrap_t)aes_unwrap,
|
||||
.hmac_sha256_vector = (esp_hmac_sha256_vector_t)hmac_sha256_vector,
|
||||
.sha256_prf = (esp_sha256_prf_t)fast_sha256_prf,
|
||||
.hmac_md5 = (esp_hmac_md5_t)hmac_md5,
|
||||
.hamc_md5_vector = (esp_hmac_md5_vector_t)hmac_md5_vector,
|
||||
.hmac_sha1 = (esp_hmac_sha1_t)hmac_sha1,
|
||||
.hmac_sha1_vector = (esp_hmac_sha1_vector_t)hmac_sha1_vector,
|
||||
.sha1_prf = (esp_sha1_prf_t)sha1_prf,
|
||||
.sha1_vector = (esp_sha1_vector_t)sha1_vector,
|
||||
.pbkdf2_sha1 = (esp_pbkdf2_sha1_t)pbkdf2_sha1,
|
||||
.rc4_skip = (esp_rc4_skip_t)rc4_skip,
|
||||
.md5_vector = (esp_md5_vector_t)md5_vector,
|
||||
.aes_encrypt = (esp_aes_encrypt_t)aes_encrypt,
|
||||
.aes_encrypt_init = (esp_aes_encrypt_init_t)aes_encrypt_init,
|
||||
.aes_encrypt_deinit = (esp_aes_encrypt_deinit_t)aes_encrypt_deinit,
|
||||
.aes_decrypt = (esp_aes_decrypt_t)aes_decrypt,
|
||||
.aes_decrypt_init = (esp_aes_decrypt_init_t)aes_decrypt_init,
|
||||
.aes_decrypt_deinit = (esp_aes_decrypt_deinit_t)aes_decrypt_deinit
|
||||
};
|
||||
|
||||
const wps_crypto_funcs_t g_wifi_default_wps_crypto_funcs = {
|
||||
.size = sizeof(wps_crypto_funcs_t),
|
||||
.version = ESP_WIFI_CRYPTO_VERSION,
|
||||
.aes_128_encrypt = (esp_aes_128_encrypt_t)aes_128_cbc_encrypt,
|
||||
.aes_128_decrypt = (esp_aes_128_decrypt_t)aes_128_cbc_decrypt,
|
||||
.crypto_mod_exp = (esp_crypto_mod_exp_t)crypto_mod_exp,
|
||||
.hmac_sha256 = (esp_hmac_sha256_t)hmac_sha256,
|
||||
.hmac_sha256_vector = (esp_hmac_sha256_vector_t)hmac_sha256_vector,
|
||||
.sha256_vector = (esp_sha256_vector_t)sha256_vector,
|
||||
.uuid_gen_mac_addr = (esp_uuid_gen_mac_addr_t)uuid_gen_mac_addr,
|
||||
.dh5_free = (esp_dh5_free_t)dh5_free,
|
||||
.wps_build_assoc_req_ie = (esp_wps_build_assoc_req_ie_t)wps_build_assoc_req_ie,
|
||||
.wps_build_assoc_resp_ie = (esp_wps_build_assoc_resp_ie_t)wps_build_assoc_resp_ie,
|
||||
.wps_build_probe_req_ie = (esp_wps_build_probe_req_ie_t)wps_build_probe_req_ie,
|
||||
.wps_build_public_key = (esp_wps_build_public_key_t)wps_build_public_key,
|
||||
.wps_enrollee_get_msg = (esp_wps_enrollee_get_msg_t)wps_enrollee_get_msg,
|
||||
.wps_enrollee_process_msg = (esp_wps_enrollee_process_msg_t)wps_enrollee_process_msg,
|
||||
.wps_generate_pin = (esp_wps_generate_pin_t)wps_generate_pin,
|
||||
.wps_is_selected_pin_registrar = (esp_wps_is_selected_pin_registrar_t)wps_is_selected_pin_registrar,
|
||||
.wps_is_selected_pbc_registrar = (esp_wps_is_selected_pbc_registrar_t)wps_is_selected_pbc_registrar,
|
||||
.eap_msg_alloc = (esp_eap_msg_alloc_t)eap_msg_alloc
|
||||
};
|
||||
|
||||
/*
|
||||
* What should notice is that the cyrpto hash type function and crypto cipher type function can not register
|
||||
* as different, i.e, if you use fast_crypto_hash_init, you should use fast_crypto_hash_update and
|
||||
* fast_crypto_hash_finish for finish hash calculate, rather than call crypto_hash_update and
|
||||
* crypto_hash_finish, so do crypto_cipher.
|
||||
*/
|
||||
const wpa2_crypto_funcs_t g_wifi_default_wpa2_crypto_funcs = {
|
||||
.size = sizeof(wpa2_crypto_funcs_t),
|
||||
.version = ESP_WIFI_CRYPTO_VERSION,
|
||||
.crypto_hash_init = (esp_crypto_hash_init_t)crypto_hash_init,
|
||||
.crypto_hash_update = (esp_crypto_hash_update_t)crypto_hash_update,
|
||||
.crypto_hash_finish = (esp_crypto_hash_finish_t)crypto_hash_finish,
|
||||
.crypto_cipher_init = (esp_crypto_cipher_init_t)crypto_cipher_init,
|
||||
.crypto_cipher_encrypt = (esp_crypto_cipher_encrypt_t)crypto_cipher_encrypt,
|
||||
.crypto_cipher_decrypt = (esp_crypto_cipher_decrypt_t)crypto_cipher_decrypt,
|
||||
.crypto_cipher_deinit = (esp_crypto_cipher_deinit_t)crypto_cipher_deinit,
|
||||
.crypto_mod_exp = (esp_crypto_mod_exp_t)crypto_mod_exp,
|
||||
.sha256_vector = (esp_sha256_vector_t)sha256_vector,
|
||||
.tls_init = (esp_tls_init_t)tls_init,
|
||||
.tls_deinit = (esp_tls_deinit_t)tls_deinit,
|
||||
.eap_peer_blob_init = (esp_eap_peer_blob_init_t)eap_peer_blob_init,
|
||||
.eap_peer_blob_deinit = (esp_eap_peer_blob_deinit_t)eap_peer_blob_deinit,
|
||||
.eap_peer_config_init = (esp_eap_peer_config_init_t)eap_peer_config_init,
|
||||
.eap_peer_config_deinit = (esp_eap_peer_config_deinit_t)eap_peer_config_deinit,
|
||||
.eap_peer_register_methods = (esp_eap_peer_register_methods_t)eap_peer_register_methods,
|
||||
.eap_peer_unregister_methods = (esp_eap_peer_unregister_methods_t)eap_peer_unregister_methods,
|
||||
.eap_deinit_prev_method = (esp_eap_deinit_prev_method_t)eap_deinit_prev_method,
|
||||
.eap_peer_get_eap_method = (esp_eap_peer_get_eap_method_t)eap_peer_get_eap_method,
|
||||
.eap_sm_abort = (esp_eap_sm_abort_t)eap_sm_abort,
|
||||
.eap_sm_build_nak = (esp_eap_sm_build_nak_t)eap_sm_build_nak,
|
||||
.eap_sm_build_identity_resp = (esp_eap_sm_build_identity_resp_t)eap_sm_build_identity_resp,
|
||||
.eap_msg_alloc = (esp_eap_msg_alloc_t)eap_msg_alloc
|
||||
};
|
||||
#endif
|
@ -1,62 +0,0 @@
|
||||
// Hardware crypto support Copyright 2017 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.
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
|
||||
#if CONFIG_SSL_USING_MBEDTLS
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
/**
|
||||
* fast_sha256_vector - SHA256 hash for data vector
|
||||
* @num_elem: Number of elements in the data vector
|
||||
* @addr: Pointers to the data areas
|
||||
* @len: Lengths of the data blocks
|
||||
* @mac: Buffer for the hash
|
||||
* Returns: 0 on success, -1 of failure
|
||||
*/
|
||||
int
|
||||
fast_sha256_vector(size_t num_elem, const uint8_t *addr[], const size_t *len,
|
||||
uint8_t *mac)
|
||||
{
|
||||
int ret = 0;
|
||||
mbedtls_sha256_context ctx;
|
||||
|
||||
mbedtls_sha256_init(&ctx);
|
||||
|
||||
if (mbedtls_sha256_starts_ret(&ctx, 0) != 0) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for(size_t index = 0; index < num_elem; index++) {
|
||||
if (mbedtls_sha256_update_ret(&ctx, addr[index], len[index]) != 0) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (mbedtls_sha256_finish_ret(&ctx, mac) != 0) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
mbedtls_sha256_free(&ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
@ -1,170 +0,0 @@
|
||||
/*
|
||||
* SHA-256 hash implementation and interface functions
|
||||
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
||||
*
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "crypto/sha256.h"
|
||||
#include "crypto/crypto.h"
|
||||
|
||||
int fast_sha256_vector(size_t num_elem, const uint8_t *addr[], const size_t *len,
|
||||
uint8_t *mac);
|
||||
|
||||
#if CONFIG_SSL_USING_MBEDTLS
|
||||
/**
|
||||
* fast_hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104)
|
||||
* @key: Key for HMAC operations
|
||||
* @key_len: Length of the key in bytes
|
||||
* @num_elem: Number of elements in the data vector
|
||||
* @addr: Pointers to the data areas
|
||||
* @len: Lengths of the data blocks
|
||||
* @mac: Buffer for the hash (32 bytes)
|
||||
*/
|
||||
void
|
||||
fast_hmac_sha256_vector(const uint8_t *key, size_t key_len, size_t num_elem,
|
||||
const uint8_t *addr[], const size_t *len, uint8_t *mac)
|
||||
{
|
||||
uint8_t k_pad[64]; /* padding - key XORd with ipad/opad */
|
||||
uint8_t tk[32];
|
||||
const uint8_t *_addr[6];
|
||||
size_t _len[6], i;
|
||||
|
||||
if (num_elem > 5) {
|
||||
/*
|
||||
* Fixed limit on the number of fragments to avoid having to
|
||||
* allocate memory (which could fail).
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* if key is longer than 64 bytes reset it to key = SHA256(key) */
|
||||
if (key_len > 64) {
|
||||
fast_sha256_vector(1, &key, &key_len, tk);
|
||||
key = tk;
|
||||
key_len = 32;
|
||||
}
|
||||
|
||||
/* the HMAC_SHA256 transform looks like:
|
||||
*
|
||||
* SHA256(K XOR opad, SHA256(K XOR ipad, text))
|
||||
*
|
||||
* where K is an n byte key
|
||||
* ipad is the byte 0x36 repeated 64 times
|
||||
* opad is the byte 0x5c repeated 64 times
|
||||
* and text is the data being protected
|
||||
*/
|
||||
|
||||
/* start out by storing key in ipad */
|
||||
os_memset(k_pad, 0, sizeof(k_pad));
|
||||
os_memcpy(k_pad, key, key_len);
|
||||
/* XOR key with ipad values */
|
||||
for (i = 0; i < 64; i++) {
|
||||
k_pad[i] ^= 0x36;
|
||||
}
|
||||
|
||||
/* perform inner SHA256 */
|
||||
_addr[0] = k_pad;
|
||||
_len[0] = 64;
|
||||
for (i = 0; i < num_elem; i++) {
|
||||
_addr[i + 1] = addr[i];
|
||||
_len[i + 1] = len[i];
|
||||
}
|
||||
fast_sha256_vector(1 + num_elem, _addr, _len, mac);
|
||||
|
||||
os_memset(k_pad, 0, sizeof(k_pad));
|
||||
os_memcpy(k_pad, key, key_len);
|
||||
/* XOR key with opad values */
|
||||
for (i = 0; i < 64; i++) {
|
||||
k_pad[i] ^= 0x5c;
|
||||
}
|
||||
|
||||
/* perform outer SHA256 */
|
||||
_addr[0] = k_pad;
|
||||
_len[0] = 64;
|
||||
_addr[1] = mac;
|
||||
_len[1] = SHA256_MAC_LEN;
|
||||
fast_sha256_vector(2, _addr, _len, mac);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* fast_hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104)
|
||||
* @key: Key for HMAC operations
|
||||
* @key_len: Length of the key in bytes
|
||||
* @data: Pointers to the data area
|
||||
* @data_len: Length of the data area
|
||||
* @mac: Buffer for the hash (20 bytes)
|
||||
*/
|
||||
void
|
||||
fast_hmac_sha256(const uint8_t *key, size_t key_len, const uint8_t *data,
|
||||
size_t data_len, uint8_t *mac)
|
||||
{
|
||||
fast_hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* fast_sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2)
|
||||
* @key: Key for PRF
|
||||
* @key_len: Length of the key in bytes
|
||||
* @label: A unique label for each purpose of the PRF
|
||||
* @data: Extra data to bind into the key
|
||||
* @data_len: Length of the data
|
||||
* @buf: Buffer for the generated pseudo-random key
|
||||
* @buf_len: Number of bytes of key to generate
|
||||
*
|
||||
* This function is used to derive new, cryptographically separate keys from a
|
||||
* given key.
|
||||
*/
|
||||
void
|
||||
fast_sha256_prf(const uint8_t *key, size_t key_len, const char *label,
|
||||
const uint8_t *data, size_t data_len, uint8_t *buf, size_t buf_len)
|
||||
{
|
||||
uint16_t counter = 1;
|
||||
size_t pos, plen;
|
||||
uint8_t hash[SHA256_MAC_LEN];
|
||||
const uint8_t *addr[4];
|
||||
size_t len[4];
|
||||
uint8_t counter_le[2], length_le[2];
|
||||
|
||||
addr[0] = counter_le;
|
||||
len[0] = 2;
|
||||
addr[1] = (uint8_t *) label;
|
||||
len[1] = os_strlen(label);
|
||||
addr[2] = data;
|
||||
len[2] = data_len;
|
||||
addr[3] = length_le;
|
||||
len[3] = sizeof(length_le);
|
||||
|
||||
WPA_PUT_LE16(length_le, buf_len * 8);
|
||||
pos = 0;
|
||||
while (pos < buf_len) {
|
||||
plen = buf_len - pos;
|
||||
WPA_PUT_LE16(counter_le, counter);
|
||||
if (plen >= SHA256_MAC_LEN) {
|
||||
fast_hmac_sha256_vector(key, key_len, 4, addr, len,
|
||||
&buf[pos]);
|
||||
pos += SHA256_MAC_LEN;
|
||||
} else {
|
||||
fast_hmac_sha256_vector(key, key_len, 4, addr, len, hash);
|
||||
os_memcpy(&buf[pos], hash, plen);
|
||||
break;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
#endif
|
@ -41,8 +41,8 @@
|
||||
* been completed successfully since WPA-PSK does not use EAP state machine.
|
||||
*/
|
||||
|
||||
#define WPA_4_4_HANDSHAKE_BIT (1<<6) //(1<<13)
|
||||
#define WPA_GROUP_HANDSHAKE_BIT (1<<7) //(1<<14)
|
||||
#define WPA_4_4_HANDSHAKE_BIT (1<<13)
|
||||
#define WPA_GROUP_HANDSHAKE_BIT (1<<14)
|
||||
struct wpa_sm gWpaSm;
|
||||
/* fix buf for tx for now */
|
||||
#define WPA_TX_MSG_BUFF_MAXLEN 200
|
||||
@ -1944,7 +1944,7 @@ int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len)
|
||||
#ifdef DEBUG_PRINT
|
||||
wpa_printf(MSG_INFO, "EAPOL1 received for %d times, sending deauth", sm->eapol1_count);
|
||||
#endif
|
||||
// esp_wifi_internal_issue_disconnect(WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT);
|
||||
esp_wifi_internal_issue_disconnect(WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT);
|
||||
goto out;
|
||||
}
|
||||
wpa_supplicant_process_1_of_4(sm, src_addr, key,
|
||||
@ -2044,9 +2044,9 @@ void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm)
|
||||
|
||||
|
||||
#ifdef ESP_SUPPLICANT
|
||||
void wpa_register(char* payload, WPA_SEND_FUNC snd_func,
|
||||
WPA_SET_ASSOC_IE set_assoc_ie_func, WPA_INSTALL_KEY ppinstallkey, WPA_GET_KEY ppgetkey, WPA_DEAUTH_FUNC wpa_deauth,
|
||||
WPA_NEG_COMPLETE wpa_neg_complete)
|
||||
bool wpa_sm_init(char * payload, WPA_SEND_FUNC snd_func,
|
||||
WPA_SET_ASSOC_IE set_assoc_ie_func, WPA_INSTALL_KEY ppinstallkey, WPA_GET_KEY ppgetkey, WPA_DEAUTH_FUNC wpa_deauth,
|
||||
WPA_NEG_COMPLETE wpa_neg_complete)
|
||||
{
|
||||
struct wpa_sm *sm = &gWpaSm;
|
||||
|
||||
@ -2140,6 +2140,9 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher,
|
||||
esp_wifi_get_config(ESP_IF_WIFI_STA, &wifi_cfg);
|
||||
sm->pmf_cfg = wifi_cfg.sta.pmf_cfg;
|
||||
sm->mgmt_group_cipher = cipher_type_map_public_to_supp(esp_wifi_sta_get_mgmt_group_cipher());
|
||||
} else {
|
||||
memset(&sm->pmf_cfg, 0, sizeof(sm->pmf_cfg));
|
||||
sm->mgmt_group_cipher = WPA_CIPHER_NONE;
|
||||
}
|
||||
#endif
|
||||
set_assoc_ie(assoc_ie_buf); /* use static buffer */
|
||||
@ -2172,11 +2175,11 @@ wpa_set_passphrase(char * passphrase, u8 *ssid, size_t ssid_len)
|
||||
/* This is really SLOW, so just re cacl while reset param */
|
||||
if (esp_wifi_sta_get_reset_param_internal() != 0) {
|
||||
// check it's psk
|
||||
if (os_strlen((char *)esp_wifi_sta_get_prof_password_internal()) == 64) {
|
||||
hexstr2bin((char *)esp_wifi_sta_get_prof_password_internal(), esp_wifi_sta_get_prof_pmk_internal(), PMK_LEN);
|
||||
if (strlen((char *)esp_wifi_sta_get_prof_password_internal()) == 64) {
|
||||
hexstr2bin((char *)esp_wifi_sta_get_prof_password_internal(), esp_wifi_sta_get_ap_info_prof_pmk_internal(), PMK_LEN);
|
||||
} else {
|
||||
pbkdf2_sha1((char *)esp_wifi_sta_get_prof_password_internal(), (char *)sta_ssid->ssid, (size_t)sta_ssid->len,
|
||||
4096, esp_wifi_sta_get_prof_pmk_internal(), PMK_LEN);
|
||||
4096, esp_wifi_sta_get_ap_info_prof_pmk_internal(), PMK_LEN);
|
||||
}
|
||||
esp_wifi_sta_update_ap_info_internal();
|
||||
esp_wifi_sta_set_reset_param_internal(0);
|
||||
@ -2372,6 +2375,15 @@ bool wpa_sta_is_cur_pmksa_set(void) {
|
||||
return (pmksa_cache_get_current(sm) != NULL);
|
||||
}
|
||||
|
||||
bool wpa_sta_cur_pmksa_matches_akm(void) {
|
||||
struct wpa_sm *sm = &gWpaSm;
|
||||
struct rsn_pmksa_cache_entry *pmksa;
|
||||
|
||||
pmksa = pmksa_cache_get_current(sm);
|
||||
return (pmksa != NULL &&
|
||||
sm->key_mgmt == pmksa->akmp);
|
||||
}
|
||||
|
||||
void wpa_sta_clear_curr_pmksa(void) {
|
||||
struct wpa_sm *sm = &gWpaSm;
|
||||
|
||||
|
@ -39,6 +39,7 @@ struct wpa_sm;
|
||||
int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len);
|
||||
bool wpa_sta_is_cur_pmksa_set(void);
|
||||
bool wpa_sta_in_4way_handshake(void);
|
||||
bool wpa_sta_cur_pmksa_matches_akm(void);
|
||||
|
||||
#define WPA_ASSERT assert
|
||||
|
||||
@ -127,6 +128,8 @@ int wpa_hook_init(void);
|
||||
|
||||
bool wpa_hook_deinit(void);
|
||||
|
||||
char * dup_binstr(const void *src, size_t len);
|
||||
|
||||
int wpa_michael_mic_failure(u16 isunicast);
|
||||
|
||||
wifi_cipher_type_t cipher_type_map_supp_to_public(uint32_t wpa_cipher);
|
||||
|
@ -152,7 +152,7 @@ typedef void (*WPA_DEAUTH_FUNC)(u8 reason_code);
|
||||
|
||||
typedef void (*WPA_NEG_COMPLETE)(void);
|
||||
|
||||
void wpa_register(char * payload, WPA_SEND_FUNC snd_func, \
|
||||
bool wpa_sm_init(char * payload, WPA_SEND_FUNC snd_func, \
|
||||
WPA_SET_ASSOC_IE set_assoc_ie_func, \
|
||||
WPA_INSTALL_KEY ppinstallkey, \
|
||||
WPA_GET_KEY ppgetkey, \
|
||||
|
@ -1009,10 +1009,19 @@ enum wps_cb_status {
|
||||
|
||||
typedef void (*wps_st_cb_t)(int status);
|
||||
|
||||
#if 1//def USE_WPS_TASK
|
||||
#define SIG_WPS_START 0
|
||||
#define SIG_WPS_RX 1
|
||||
#define SIG_WPS_NUM 2
|
||||
#ifdef USE_WPS_TASK
|
||||
enum wps_sig_type {
|
||||
SIG_WPS_ENABLE = 1, //1
|
||||
SIG_WPS_DISABLE, //2
|
||||
SIG_WPS_START, //3
|
||||
SIG_WPS_RX, //4
|
||||
SIG_WPS_TIMER_TIMEOUT, //5
|
||||
SIG_WPS_TIMER_MSG_TIMEOUT, //6
|
||||
SIG_WPS_TIMER_SUCCESS_CB, //7
|
||||
SIG_WPS_TIMER_SCAN, //8
|
||||
SIG_WPS_TIMER_EAPOL_START, //9
|
||||
SIG_WPS_NUM, //10
|
||||
};
|
||||
#endif
|
||||
|
||||
#define WPS_EAP_EXT_VENDOR_TYPE "WFA-SimpleConfig-Enrollee-1-0"
|
||||
@ -1025,13 +1034,14 @@ struct wps_sm {
|
||||
u8 identity_len;
|
||||
u8 ownaddr[ETH_ALEN];
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 ssid[32];
|
||||
u8 ssid_len;
|
||||
u8 ssid[MAX_WPS_AP_CRED][MAX_SSID_LEN];
|
||||
u8 ssid_len[MAX_WPS_AP_CRED];
|
||||
char key[MAX_WPS_AP_CRED][MAX_PASSPHRASE_LEN];
|
||||
u8 key_len[MAX_WPS_AP_CRED];
|
||||
u8 ap_cred_cnt;
|
||||
struct wps_device_data *dev;
|
||||
u8 uuid[16];
|
||||
u8 eapol_version;
|
||||
char key[64];
|
||||
u8 key_len;
|
||||
ETSTimer wps_timeout_timer;
|
||||
ETSTimer wps_msg_timeout_timer;
|
||||
ETSTimer wps_scan_timer;
|
||||
@ -1055,8 +1065,8 @@ struct wps_sm {
|
||||
#define WIFI_CAPINFO_PRIVACY 0x0010
|
||||
|
||||
struct wps_sm *wps_sm_get(void);
|
||||
int wps_ssid_save(u8 *ssid, u8 ssid_len);
|
||||
int wps_key_save(char *key, u8 key_len);
|
||||
int wps_ssid_save(u8 *ssid, u8 ssid_len, u8 idx);
|
||||
int wps_key_save(char *key, u8 key_len, u8 idx);
|
||||
int wps_station_wps_register_cb(wps_st_cb_t cb);
|
||||
int wps_station_wps_unregister_cb(void);
|
||||
int wps_start_pending(void);
|
||||
|
@ -654,7 +654,7 @@ static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2)
|
||||
|
||||
|
||||
static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
|
||||
size_t cred_len, int wps2)
|
||||
size_t cred_len, int cred_idx, int wps2)
|
||||
{
|
||||
struct wps_parse_attr *attr;
|
||||
struct wpabuf msg;
|
||||
@ -714,9 +714,8 @@ static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
|
||||
goto _out;
|
||||
}
|
||||
#endif /* CONFIG_WPS2 */
|
||||
|
||||
wps_ssid_save(wps->cred.ssid, wps->cred.ssid_len);
|
||||
wps_key_save((char *)wps->cred.key, wps->cred.key_len);
|
||||
wps_ssid_save(wps->cred.ssid, wps->cred.ssid_len, cred_idx);
|
||||
wps_key_save((char *)wps->cred.key, wps->cred.key_len, cred_idx);
|
||||
|
||||
if (wps->wps->cred_cb) {
|
||||
wps->cred.cred_attr = cred - 4;
|
||||
@ -751,7 +750,7 @@ static int wps_process_creds(struct wps_data *wps, const u8 *cred[],
|
||||
|
||||
for (i = 0; i < num_cred; i++) {
|
||||
int res;
|
||||
res = wps_process_cred_e(wps, cred[i], cred_len[i], wps2);
|
||||
res = wps_process_cred_e(wps, cred[i], cred_len[i], i, wps2);
|
||||
if (res == 0)
|
||||
ok++;
|
||||
else if (res == -2) {
|
||||
|
@ -125,40 +125,6 @@ struct wps_data {
|
||||
#endif
|
||||
};
|
||||
|
||||
#if 0
|
||||
typedef enum wps_type {
|
||||
WPS_TYPE_DISABLE = 0,
|
||||
WPS_TYPE_E_PBC,
|
||||
WPS_TYPE_E_PIN,
|
||||
WPS_TYPE_E_DISPLAY,
|
||||
WPS_TYPE_E_MAX,
|
||||
WPS_TYPE_R_PBC,
|
||||
WPS_TYPE_R_PIN,
|
||||
WPS_TYPE_R_DISPLAY,
|
||||
WPS_TYPE_R_MAX,
|
||||
WPS_TYPE_ALL_MAX,
|
||||
} WPS_TYPE_t;
|
||||
|
||||
#define WPS_MAX_MANUFACTURER_LEN 65
|
||||
#define WPS_MAX_MODEL_NUMBER_LEN 33
|
||||
#define WPS_MAX_MODEL_NAME_LEN 33
|
||||
#define WPS_MAX_DEV_NAME_LEN 33
|
||||
typedef struct {
|
||||
char manufacturer[WPS_MAX_MANUFACTURER_LEN];
|
||||
char model_number[WPS_MAX_MODEL_NUMBER_LEN];
|
||||
char model_name[WPS_MAX_MODEL_NAME_LEN];
|
||||
char device_name[WPS_MAX_DEV_NAME_LEN];
|
||||
} esp_factory_information_t;
|
||||
|
||||
typedef struct {
|
||||
WPS_TYPE_t wps_type;
|
||||
const wps_crypto_funcs_t *crypto_funcs;
|
||||
esp_factory_information_t factory_info;
|
||||
}esp_wps_config_t;
|
||||
|
||||
wps_crypto_funcs_t wps_crypto_funcs;
|
||||
#endif
|
||||
|
||||
/* wps_common.c */
|
||||
void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,
|
||||
const char *label, u8 *res, size_t res_len);
|
||||
|
@ -101,7 +101,6 @@ static void initialise_wifi(void)
|
||||
unsigned int ca_pem_bytes = ca_pem_end - ca_pem_start;
|
||||
unsigned int client_crt_bytes = client_crt_end - client_crt_start;
|
||||
unsigned int client_key_bytes = client_key_end - client_key_start;
|
||||
esp_wpa2_config_t config = WPA2_CONFIG_INIT_DEFAULT();
|
||||
|
||||
tcpip_adapter_init();
|
||||
wifi_event_group = xEventGroupCreate();
|
||||
@ -129,7 +128,7 @@ static void initialise_wifi(void)
|
||||
ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_set_password((uint8_t*)EXAMPLE_EAP_PASSWORD, strlen(EXAMPLE_EAP_PASSWORD)));
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_enable(&config));
|
||||
ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_enable());
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user