diff --git a/README.md b/README.md index 77db82e1..2e84d1fe 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ This firmware uses [Espressif's IDF](https://github.com/espressif/esp-idf) ## Building -1. [Download the ESP32 toolchain](http://esp-idf.readthedocs.io/en/v3.1/get-started/index.html#setup-toolchain) +1. [Download the ESP32 toolchain](http://esp-idf.readthedocs.io/en/v3.3.1/get-started/index.html#setup-toolchain) 1. Extract it and add it to your `PATH`: `export PATH=$PATH:/bin` -1. Clone **v3.3** of the IDF: `git clone --branch v3.3 --recursive https://github.com/espressif/esp-idf.git` +1. Clone **v3.3.1** of the IDF: `git clone --branch v3.3.1 --recursive https://github.com/espressif/esp-idf.git` 1. Set the `IDF_PATH` environment variable: `export IDF_PATH=` 1. Run `make` to build the firmware (in the directory of this read me) 1. Load the `Tools -> SerialNINAPassthrough` example sketch on to the board diff --git a/arduino/libraries/WiFi/src/WiFi.cpp b/arduino/libraries/WiFi/src/WiFi.cpp index e1580705..e9330555 100644 --- a/arduino/libraries/WiFi/src/WiFi.cpp +++ b/arduino/libraries/WiFi/src/WiFi.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -39,7 +40,10 @@ WiFiClass::WiFiClass() : _reasonCode(0), _interface(ESP_IF_WIFI_STA), _onReceiveCallback(NULL), - _onDisconnectCallback(NULL) + _onDisconnectCallback(NULL), + _wpa2Cert(NULL), + _wpa2Key(NULL), + _wpa2RootCA(NULL) { _eventGroup = xEventGroupCreate(); memset(&_apRecord, 0x00, sizeof(_apRecord)); @@ -299,6 +303,82 @@ uint8_t WiFiClass::beginAP(const char *ssid, const char* key, uint8_t channel) return _status; } +uint8_t WiFiClass::beginEnterprise(const char* ssid, const char* username, const char* password, const char* identity, const char* rootCA) +{ + esp_wifi_sta_wpa2_ent_clear_username(); + esp_wifi_sta_wpa2_ent_clear_password(); + esp_wifi_sta_wpa2_ent_clear_identity(); + esp_wifi_sta_wpa2_ent_clear_ca_cert(); + esp_wifi_sta_wpa2_ent_clear_cert_key(); + + esp_wpa2_config_t config = WPA2_CONFIG_INIT_DEFAULT(); + + esp_wifi_sta_wpa2_ent_enable(&config); + + int usernameLen = strlen(username); + if (usernameLen) { + esp_wifi_sta_wpa2_ent_set_username((const unsigned char*)username, usernameLen); + } + + int passwordLen = strlen(password); + if (passwordLen) { + esp_wifi_sta_wpa2_ent_set_password((const unsigned char*)password, passwordLen); + } + + int identityLen = strlen(identity); + if (identityLen) { + esp_wifi_sta_wpa2_ent_set_identity((const unsigned char*)identity, identityLen); + } + + int rootCALen = strlen(rootCA); + if (rootCALen) { + _wpa2RootCA = (char*)realloc(_wpa2RootCA, rootCALen + 1); + memcpy(_wpa2RootCA, rootCA, rootCALen + 1); + + esp_wifi_sta_wpa2_ent_set_ca_cert((const unsigned char*)_wpa2RootCA, rootCALen + 1); + } + + return begin(ssid); +} + +uint8_t WiFiClass::beginEnterpriseTLS(const char* ssid, const char* cert, const char* key, const char* identity, const char* rootCA) +{ + esp_wifi_sta_wpa2_ent_clear_username(); + esp_wifi_sta_wpa2_ent_clear_password(); + esp_wifi_sta_wpa2_ent_clear_identity(); + esp_wifi_sta_wpa2_ent_clear_ca_cert(); + esp_wifi_sta_wpa2_ent_clear_cert_key(); + + esp_wpa2_config_t config = WPA2_CONFIG_INIT_DEFAULT(); + + esp_wifi_sta_wpa2_ent_enable(&config); + + int certLen = strlen(cert); + int keyLen = strlen(key); + + _wpa2Cert = (char*)realloc(_wpa2Cert, certLen + 1); + memcpy(_wpa2Cert, cert, certLen + 1); + _wpa2Key = (char*)realloc(_wpa2Key, keyLen + 1); + memcpy(_wpa2Key, key, keyLen + 1); + + esp_wifi_sta_wpa2_ent_set_cert_key((const unsigned char*)_wpa2Cert, certLen + 1, (const unsigned char*)_wpa2Key, keyLen + 1, NULL, 0); + + int identityLen = strlen(identity); + if (identityLen) { + esp_wifi_sta_wpa2_ent_set_identity((const unsigned char*)identity, identityLen); + } + + int rootCALen = strlen(rootCA); + if (rootCALen) { + _wpa2RootCA = (char*)realloc(_wpa2RootCA, rootCALen + 1); + memcpy(_wpa2RootCA, rootCA, rootCALen + 1); + + esp_wifi_sta_wpa2_ent_set_ca_cert((const unsigned char*)_wpa2RootCA, rootCALen + 1); + } + + return begin(ssid); +} + void WiFiClass::config(/*IPAddress*/uint32_t local_ip, /*IPAddress*/uint32_t gateway, /*IPAddress*/uint32_t subnet) { dns_clear_servers(true); diff --git a/arduino/libraries/WiFi/src/WiFi.h b/arduino/libraries/WiFi/src/WiFi.h index a5090350..00c4551b 100644 --- a/arduino/libraries/WiFi/src/WiFi.h +++ b/arduino/libraries/WiFi/src/WiFi.h @@ -59,6 +59,8 @@ class WiFiClass uint8_t beginAP(const char *ssid, uint8_t key_idx, const char* key, uint8_t channel); uint8_t beginAP(const char *ssid, const char* key, uint8_t channel); + uint8_t beginEnterprise(const char* ssid, const char* username, const char* password, const char* identity, const char* rootCA); + uint8_t beginEnterpriseTLS(const char* ssid, const char* cert, const char* key, const char* identity, const char* rootCA); void config(/*IPAddress*/uint32_t local_ip, /*IPAddress*/uint32_t gateway, /*IPAddress*/uint32_t subnet); @@ -129,6 +131,10 @@ class WiFiClass void (*_onReceiveCallback)(void); void (*_onDisconnectCallback)(void); + + char* _wpa2Cert; + char* _wpa2Key; + char* _wpa2RootCA; }; extern WiFiClass WiFi; diff --git a/main/CommandHandler.cpp b/main/CommandHandler.cpp index 9b53b2c7..b951bb11 100644 --- a/main/CommandHandler.cpp +++ b/main/CommandHandler.cpp @@ -837,6 +837,126 @@ int getIdxChannel(const uint8_t command[], uint8_t response[]) return 6; } +int setEnt(const uint8_t command[], uint8_t response[]) +{ + const uint8_t* commandPtr = &command[3]; + uint8_t eapType; + char ssid[32 + 1]; + + memset(ssid, 0x00, sizeof(ssid)); + + // EAP Type - length + uint16_t eapTypeLen = (commandPtr[0] << 8) | commandPtr[1]; + commandPtr += sizeof(eapTypeLen); + + // EAP Type - data + memcpy(&eapType, commandPtr, sizeof(eapType)); + commandPtr += sizeof(eapType); + + // SSID - length + uint16_t ssidLen = (commandPtr[0] << 8) | commandPtr[1]; + commandPtr += sizeof(ssidLen); + + // SSID - data + memcpy(ssid, commandPtr, ssidLen); + commandPtr += ssidLen; + + if (eapType == 0) { + // PEAP/MSCHAPv2 + char username[128 + 1]; + char password[128 + 1]; + char identity[128 + 1]; + const char* rootCA; + + memset(username, 0x00, sizeof(username)); + memset(password, 0x00, sizeof(password)); + memset(identity, 0x00, sizeof(identity)); + + // username - length + uint16_t usernameLen = (commandPtr[0] << 8) | commandPtr[1]; + commandPtr += sizeof(usernameLen); + + // username - data + memcpy(username, commandPtr, usernameLen); + commandPtr += usernameLen; + + // password - length + uint16_t passwordLen = (commandPtr[0] << 8) | commandPtr[1]; + commandPtr += sizeof(passwordLen); + + // password - data + memcpy(password, commandPtr, passwordLen); + commandPtr += passwordLen; + + // identity - length + uint16_t identityLen = (commandPtr[0] << 8) | commandPtr[1]; + commandPtr += sizeof(identityLen); + + // identity - data + memcpy(identity, commandPtr, identityLen); + commandPtr += identityLen; + + // rootCA - length + uint16_t rootCALen = (commandPtr[0] << 8) | commandPtr[1]; + memcpy(&rootCALen, commandPtr, sizeof(rootCALen)); + commandPtr += sizeof(rootCALen); + + // rootCA - data + rootCA = (const char*)commandPtr; + commandPtr += rootCALen; + + WiFi.beginEnterprise(ssid, username, password, identity, rootCA); + } else { + // EAP-TLS + const char* cert; + const char* key; + char identity[128 + 1]; + const char* rootCA; + + memset(identity, 0x00, sizeof(identity)); + + // cert - length + uint16_t certLen = (commandPtr[0] << 8) | commandPtr[1]; + commandPtr += sizeof(certLen); + + // cert - data + cert = (const char*)commandPtr; + commandPtr += certLen; + + // key - length + uint16_t keyLen = (commandPtr[0] << 8) | commandPtr[1]; + commandPtr += sizeof(keyLen); + + // key - data + key = (const char*)commandPtr; + commandPtr += keyLen; + + // identity - length + uint16_t identityLen = (commandPtr[0] << 8) | commandPtr[1]; + commandPtr += sizeof(identityLen); + + // identity - data + memcpy(identity, commandPtr, identityLen); + commandPtr += identityLen; + + // rootCA - length + uint16_t rootCALen = (commandPtr[0] << 8) | commandPtr[1]; + commandPtr += sizeof(rootCALen); + + // rootCA - data + rootCA = (const char*)commandPtr; + commandPtr += rootCALen; + + WiFi.beginEnterpriseTLS(ssid, cert, key, identity, rootCA); + } + + response[2] = 1; // number of parameters + response[3] = 1; // parameter 1 length + response[4] = 1; + + return 6; +} + int sendDataTcp(const uint8_t command[], uint8_t response[]) { uint8_t socket; @@ -1006,7 +1126,7 @@ const CommandHandlerType commandHandlers[] = { disconnect, NULL, getIdxRSSI, getIdxEnct, reqHostByName, getHostByName, startScanNetworks, getFwVersion, NULL, sendUDPdata, getRemoteData, getTime, getIdxBSSID, getIdxChannel, ping, getSocket, // 0x40 -> 0x4f - NULL, NULL, NULL, NULL, sendDataTcp, getDataBufTcp, insertDataBuf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + setEnt, NULL, NULL, NULL, sendDataTcp, getDataBufTcp, insertDataBuf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 0x50 -> 0x5f setPinMode, setDigitalWrite, setAnalogWrite, diff --git a/sdkconfig b/sdkconfig index 1e319800..2acf7093 100644 --- a/sdkconfig +++ b/sdkconfig @@ -3,6 +3,7 @@ # Espressif IoT Development Framework Configuration # CONFIG_IDF_TARGET="esp32" +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 # # SDK tool configuration @@ -140,6 +141,7 @@ CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY= CONFIG_BTDM_CONTROLLER_MODE_BTDM= CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=3 +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=3 CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 @@ -206,6 +208,12 @@ CONFIG_EFUSE_MAX_BLK_LEN=192 # ESP32-specific # CONFIG_IDF_TARGET_ESP32=y +CONFIG_ESP32_REV_MIN_0=y +CONFIG_ESP32_REV_MIN_1= +CONFIG_ESP32_REV_MIN_2= +CONFIG_ESP32_REV_MIN_3= +CONFIG_ESP32_REV_MIN=0 +CONFIG_ESP32_DPORT_WORKAROUND=y CONFIG_ESP32_DEFAULT_CPU_FREQ_80=y CONFIG_ESP32_DEFAULT_CPU_FREQ_160= CONFIG_ESP32_DEFAULT_CPU_FREQ_240= @@ -279,6 +287,7 @@ CONFIG_DISABLE_BASIC_ROM_CONSOLE= CONFIG_ESP_TIMER_PROFILING= CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS= CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL=5 # # Wi-Fi @@ -332,6 +341,7 @@ CONFIG_EVENT_LOOP_PROFILING= # ESP HTTP client # CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH= # # HTTP Server @@ -339,6 +349,8 @@ CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +CONFIG_HTTPD_LOG_PURGE_DATA= # # ESP HTTPS OTA @@ -443,6 +455,8 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY= CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS= CONFIG_FREERTOS_DEBUG_INTERNALS= CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE= # # Heap memory debugging @@ -479,7 +493,6 @@ CONFIG_USE_ONLY_LWIP_SELECT= CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y CONFIG_LWIP_SO_RCVBUF=y -CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 CONFIG_LWIP_IP_FRAG= CONFIG_LWIP_IP_REASSEMBLY= CONFIG_LWIP_STATS= @@ -540,6 +553,12 @@ CONFIG_LWIP_BROADCAST_PING= # CONFIG_LWIP_MAX_RAW_PCBS=16 +# +# SNTP +# +CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 + # # mbedTLS # @@ -549,6 +568,8 @@ CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC= CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN= CONFIG_MBEDTLS_DEBUG= +CONFIG_MBEDTLS_ECP_RESTARTABLE= +CONFIG_MBEDTLS_CMAC_C= CONFIG_MBEDTLS_HARDWARE_AES=y CONFIG_MBEDTLS_HARDWARE_MPI= CONFIG_MBEDTLS_HARDWARE_SHA= @@ -666,6 +687,9 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" CONFIG_SPI_FLASH_VERIFY_WRITE= CONFIG_SPI_FLASH_ENABLE_COUNTERS= CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS= +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED= CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 @@ -728,3 +752,8 @@ CONFIG_SUPPORT_TERMIOS=y CONFIG_WL_SECTOR_SIZE_512= CONFIG_WL_SECTOR_SIZE_4096=y CONFIG_WL_SECTOR_SIZE=4096 + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16