feat(wpa_supplicant): refactor wpa_supplicant

This commit is contained in:
Zhang Jun Hao
2020-08-18 10:25:17 +08:00
parent 38b91692da
commit e716bb876d
36 changed files with 3764 additions and 1630 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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.

View File

@ -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") \

View File

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

View File

@ -117,6 +117,7 @@ struct wpa_state_machine {
int pending_1_of_4_timeout;
u32 index;
ETSTimer resend_eapol;
};

View File

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

View File

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

View 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;
}

View File

@ -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
View 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(&param);
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(&param);
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;

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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