diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 85a94e77e..3fa06b28d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,7 +43,7 @@ build_ssc: - git clone $GITLAB_SSH_SERVER/yinling/SSC.git - cd SSC # try checkout same branch - - git checkout "${CI_BUILD_REF_NAME}_8266" || echo "Using default branch..." + - git checkout "release/v3.3_8266" || echo "Using default branch..." - ./gen_misc_rtos.sh push_master_to_github: diff --git a/SUPPORT_POLICY_CN.md b/SUPPORT_POLICY_CN.md new file mode 100644 index 000000000..4dceb76ab --- /dev/null +++ b/SUPPORT_POLICY_CN.md @@ -0,0 +1,54 @@ +有关 ESP8266 RTOS SDK 的最新支持政策,详见 [支持期限政策](./SUPPORT_POLICY_CN.md)。 +支持期限政策 +================= + +* [English Version](./SUPPORT_POLICY_EN.md) + +ESP8266 RTOS SDK 的每个主要版本和次要版本(如 V3.0、V3.1 等)自其首次稳定版本发布之日起将维护 18 个月。 + +维护意味着 ESP8266 RTOS SDK 团队将会对 GitHub 上的发布分支继续进行 bug 修复、安全修补等,并根据需求定期发布新的 bugfix 版本。 + +在某一版本支持期限结束,停止更新维护 (EOL) 前,建议用户升级到较新的 ESP8266 RTOS SDK 版本。根据《支持期限政策》,我们将停止对 EOL 版本进行 bug 修复。 + +《支持期限政策》不适用于预发布版本(包括 beta、preview、`-rc` 和 `-dev` 版本等)。有时,在发布的版本中存在被标记为 "Preview" 的特定功能,则该功能也不在支持期限内。 + +长期支持版本 +------------ + +有些发布版本(例如 ESP8266 RTOS SDK V3.1)属于长期支持 (LTS) 版本。LTS 版本将自其首次稳定版本发布之日起维护 30 个月(2.5 年)。 + +关于长期维护版本,在 github 上面正式的`第1次`发布该版本 release 的时候,会在标题上额外标注 `(LTS)`,例如: + +``` +ESP8266 RTOS SDK Release v3.4 (LTS) +``` + +后续的维护版本不会再额外标注 `(LTS)`,例如: + +``` +ESP8266 RTOS SDK Release v3.4.1 +``` + +示例 +----- + +ESP8266 RTOS SDK V3.1 于 2019 年 01 月发布,属于 LTS 版本,自正式发布日开始将维护 30 个月至 2021 年 07 月停止。 + +- V3.1 的首个发布版本为 2019 年 01 月发布的 `v3.1`。 +- ESP8266 RTOS SDK 团队将持续进行 bug 修复、安全修补等更新,并 backport 至分支 `release/v3.1`。 +- 定期从 release 分支创建稳定的 bugfix 版本,比如,`v3.1.1`、`v3.1.2` 等,并建议用户保持使用最新的 bugfix 版本。 +- V3.1 的 bugfix 版本发布将持续 30 个月至 2021 年 07 月,届时所有 V3.1.x 将停止更新维护。 + +现有版本 +-------- + +ESP8266 RTOS SDK V3.3 及所有后续更新版本都将遵守该《支持期限政策》。每一版本发布时将同时公布其支持期限。 + +对于该政策公布之日前发布的其他版本,应适用下述支持期限: + +- ESP8266 RTOS SDK V3.3.x 将维护至 2021 年 12 月。 +- ESP8266 RTOS SDK V3.2.x 将维护至 2020 年 12 月。 +- ESP8266 RTOS SDK V3.1.x 作为长期维护版本,将维护至 2021 年 7 月。 +- ESP8266 RTOS SDK V3.0.x 将维护至 2020 年 10 月。 +- ESP8266 RTOS SDK V2.1.x 作为长期维护版本,将维护至 2021 年 4 月。 +- ESP8266 RTOS SDK V2.0.x 及之前的版本均已停止更新维护 (EOL)。 \ No newline at end of file diff --git a/SUPPORT_POLICY_EN.md b/SUPPORT_POLICY_EN.md new file mode 100644 index 000000000..cb8c5533e --- /dev/null +++ b/SUPPORT_POLICY_EN.md @@ -0,0 +1,56 @@ +The latest support policy for ESP8266 RTOS SDK can be found at [Support Policy](./SUPPORT_POLICY_EN.md). + +Support Period Policy +================= + +* [中文版](./SUPPORT_POLICY_CN.md) + +Each ESP8266 RTOS SDK major and minor release (V3.0, V3.1, etc) is supported for 18 months after the initial stable release date. + +Supported means that the ESP8266 RTOS SDK team will continue to apply bug fixes, security fixes, etc to the release branch on GitHub, and periodically make new bugfix releases as needed. + +Users are encouraged to upgrade to a newer ESP8266 RTOS SDK release before the support period finishes and the release becomes End of Life (EOL). It is our policy to not continue fixing bugs in End of Life releases. + +Pre-release versions (betas, previews, -rc and -dev versions, etc) are not covered by any support period. Sometimes a particular feature is marked as "Preview" in a release, which means it is also not covered by the support period. + + +Long Term Support releases +------------ + +Some releases (for example, ESP8266 RTOS SDK V3.1) are designated Long Term Support (LTS). LTS releases are supported for 30 months (2.5 years) after the initial stable release date. + +We will add a `(LTS)` tag when we release a long term support version on GitHub at the first time. For example: + +``` +ESP8266 RTOS SDK Release v3.4 (LTS) +``` + +But we will not add `(LTS)` tag to the following bug fix versions. For example: + +``` +ESP8266 RTOS SDK Release v3.4.1 +``` + +Example +----- + +ESP8266 RTOS SDK V3.1 was released in January 2019 and is a Long Term Support (LTS) release, meaning it will be supported for 30 months until July 2021. + +- The first V3.1 release was `v3.1` in January 2019. +- The ESP8266 RTOS SDK team continues to backport bug fixes, security fixes, etc to the release branch `release/v3.1`。 +- Periodically stable bugfix releases are created from the release branch. For example `v3.1.1`、`v3.1.2`, etc. Users are encouraged to always update to the latest bugfix release. +- V3.1 bugfix releases continue until July 2021, when all V3.1.x releases become End of Life. + +Existing Releases +-------- + +ESP8266 RTOS SDK V3.3 and all newer releases will follow this support period policy. The support period for each release will be announced when the release is made. + +For releases made before the support period policy was announced, the following support periods apply: + +- ESP8266 RTOS SDK V3.2.x will be supported until December 2021. +- ESP8266 RTOS SDK V3.2.x will be supported until December 2020. +- ESP8266 RTOS SDK V3.1.x is Long Term Support (LTS) release, will be supported until July 2021. +- ESP8266 RTOS SDK V3.0.x will be supported until October 2020. +- ESP8266 RTOS SDK V2.1.x is Long Term Support (LTS) release, will be supported until April 2021. +- ESP8266 RTOS SDK V2.0.x and earlier versions are already End of Life. diff --git a/components/aws_iot/port/network_mbedtls_wrapper.c b/components/aws_iot/port/network_mbedtls_wrapper.c index 5b70ad309..131336db2 100644 --- a/components/aws_iot/port/network_mbedtls_wrapper.c +++ b/components/aws_iot/port/network_mbedtls_wrapper.c @@ -107,7 +107,7 @@ IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params) { ret = SSL_CONNECTION_ERROR; } else { int tls_ret = esp_tls_conn_new_sync(pNetwork->tlsConnectParams.pDestinationURL, strlen(pNetwork->tlsConnectParams.pDestinationURL), pNetwork->tlsConnectParams.DestinationPort, &cfg, tls); - if (tls_ret) { + if (tls_ret == -1) { ret = SSL_CONNECTION_ERROR; esp_tls_conn_delete(tls); } diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 9953b77b1..51d060b16 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -10,6 +10,15 @@ config BOOTLOADER_INIT_SPI_FLASH If your system bootloader is based on v3.0, the option must not be enable, because the v3.0 bootloader don't support this function. +config BOOTLOADER_DISABLE_JTAG_IO + bool "Bootloader disable JTAG I/O" + default n + help + Enable this option, when SoC brings up and bootloader initializes hardware, it will + disable JTAG's I/O and set these GPIOs to be normal I/O with inputting mode. + + If users use JTAG to help develop, please disable this option. + choice LOG_BOOTLOADER_LEVEL bool "Bootloader log verbosity" default LOG_BOOTLOADER_LEVEL_INFO diff --git a/components/bootloader_support/src/bootloader_init.c b/components/bootloader_support/src/bootloader_init.c index 3035b10b3..f10d75e69 100644 --- a/components/bootloader_support/src/bootloader_init.c +++ b/components/bootloader_support/src/bootloader_init.c @@ -613,6 +613,17 @@ esp_err_t bootloader_init() static esp_err_t bootloader_main() { +#ifdef CONFIG_BOOTLOADER_DISABLE_JTAG_IO + /* Set GPIO 12-15 to be normal GPIO */ + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15); + + /* Set GPIO 12-15 to be input mode */ + GPIO_REG_WRITE(GPIO_ENABLE_W1TC_ADDRESS, BIT12 | BIT13 | BIT14 | BIT15); +#endif + uart_console_configure(); esp_image_header_t fhdr; diff --git a/components/bootloader_support/src/bootloader_sha.c b/components/bootloader_support/src/bootloader_sha.c index 2b1bd5846..782665678 100644 --- a/components/bootloader_support/src/bootloader_sha.c +++ b/components/bootloader_support/src/bootloader_sha.c @@ -222,11 +222,11 @@ void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest // typedef esp_sha_t* bootloader_sha256_handle_t; -static esp_sha_t s_sha256_ctx; +static esp_sha256_t s_sha256_ctx; bootloader_sha256_handle_t bootloader_sha256_start() { - esp_sha_t *ctx = &s_sha256_ctx; + esp_sha256_t *ctx = &s_sha256_ctx; esp_sha256_init(ctx); @@ -235,12 +235,12 @@ bootloader_sha256_handle_t bootloader_sha256_start() void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len) { - esp_sha256_update((esp_sha_t *)handle, data, data_len); + esp_sha256_update((esp_sha256_t *)handle, data, data_len); } void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest) { - esp_sha256_finish((esp_sha_t *)handle, digest); + esp_sha256_finish((esp_sha256_t *)handle, digest); } #endif diff --git a/components/esp-tls/Kconfig b/components/esp-tls/Kconfig index 0bfe9a6e2..dc9154170 100644 --- a/components/esp-tls/Kconfig +++ b/components/esp-tls/Kconfig @@ -14,22 +14,22 @@ menu "ESP-TLS" config ESP_TLS_SERVER bool "Enable ESP-TLS Server" - depends on ESP_TLS_USING_MBEDTLS default n help - Enable support for creating server side SSL/TLS session, uses the mbedtls crypto library + Enable support for creating server side SSL/TLS session, available for mbedTLS + as well as wolfSSL TLS library. config ESP_TLS_PSK_VERIFICATION bool "Enable PSK verification" - depends on ESP_TLS_USING_MBEDTLS - select MBEDTLS_PSK_MODES - select MBEDTLS_KEY_EXCHANGE_PSK - select MBEDTLS_KEY_EXCHANGE_DHE_PSK - select MBEDTLS_KEY_EXCHANGE_ECDHE_PSK - select MBEDTLS_KEY_EXCHANGE_RSA_PSK + select MBEDTLS_PSK_MODES if ESP_TLS_USING_MBEDTLS + select MBEDTLS_KEY_EXCHANGE_PSK if ESP_TLS_USING_MBEDTLS + select MBEDTLS_KEY_EXCHANGE_DHE_PSK if ESP_TLS_USING_MBEDTLS + select MBEDTLS_KEY_EXCHANGE_ECDHE_PSK if ESP_TLS_USING_MBEDTLS + select MBEDTLS_KEY_EXCHANGE_RSA_PSK if ESP_TLS_USING_MBEDTLS default n help - Enable support for pre shared key ciphers, uses the mbedtls crypto library + Enable support for pre shared key ciphers, supported for both mbedTLS as well as + wolfSSL TLS library. config ESP_WOLFSSL_SMALL_CERT_VERIFY bool "Enable SMALL_CERT_VERIFY" diff --git a/components/esp-tls/esp_tls.c b/components/esp-tls/esp_tls.c index cd45d218b..8aa5afe5a 100644 --- a/components/esp-tls/esp_tls.c +++ b/components/esp-tls/esp_tls.c @@ -60,6 +60,10 @@ static const char *TAG = "esp-tls"; #define _esp_tls_read esp_wolfssl_read #define _esp_tls_write esp_wolfssl_write #define _esp_tls_conn_delete esp_wolfssl_conn_delete +#ifdef CONFIG_ESP_TLS_SERVER +#define _esp_tls_server_session_create esp_wolfssl_server_session_create +#define _esp_tls_server_session_delete esp_wolfssl_server_session_delete +#endif /* CONFIG_ESP_TLS_SERVER */ #define _esp_tls_get_bytes_avail esp_wolfssl_get_bytes_avail #define _esp_tls_init_global_ca_store esp_wolfssl_init_global_ca_store #define _esp_tls_set_global_ca_store esp_wolfssl_set_global_ca_store /*!< Callback function for setting global CA store data for TLS/SSL */ @@ -115,8 +119,9 @@ esp_tls_t *esp_tls_init(void) return NULL; } #ifdef CONFIG_ESP_TLS_USING_MBEDTLS - tls->server_fd.fd = tls->sockfd = -1; + tls->server_fd.fd = -1; #endif + tls->sockfd = -1; return tls; } @@ -193,7 +198,11 @@ static esp_err_t esp_tcp_connect(const char *host, int hostlen, int port, int *s } if (cfg->non_block) { int flags = fcntl(fd, F_GETFL, 0); - fcntl(fd, F_SETFL, flags | O_NONBLOCK); + ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK); + if (ret < 0) { + ESP_LOGE(TAG, "Failed to configure the socket as non-blocking (errno %d)", errno); + goto err_freesocket; + } } } @@ -259,9 +268,9 @@ static int esp_tls_low_level_conn(const char *hostname, int hostlen, int port, c ms_to_timeval(cfg->timeout_ms, &tv); /* In case of non-blocking I/O, we use the select() API to check whether - connection has been estbalished or not*/ + connection has been established or not*/ if (select(tls->sockfd + 1, &tls->rset, &tls->wset, NULL, - cfg->timeout_ms ? &tv : NULL) == 0) { + cfg->timeout_ms>0 ? &tv : NULL) == 0) { ESP_LOGD(TAG, "select() timed out"); return 0; } @@ -309,12 +318,13 @@ static int esp_tls_low_level_conn(const char *hostname, int hostlen, int port, c */ esp_tls_t *esp_tls_conn_new(const char *hostname, int hostlen, int port, const esp_tls_cfg_t *cfg) { - esp_tls_t *tls = (esp_tls_t *)calloc(1, sizeof(esp_tls_t)); + esp_tls_t *tls = esp_tls_init(); if (!tls) { return NULL; } /* esp_tls_conn_new() API establishes connection in a blocking manner thus this loop ensures that esp_tls_conn_new() API returns only after connection is established unless there is an error*/ + size_t start = xTaskGetTickCount(); while (1) { int ret = esp_tls_low_level_conn(hostname, hostlen, port, cfg, tls); if (ret == 1) { @@ -323,6 +333,14 @@ esp_tls_t *esp_tls_conn_new(const char *hostname, int hostlen, int port, const e esp_tls_conn_delete(tls); ESP_LOGE(TAG, "Failed to open new connection"); return NULL; + } else if (ret == 0 && cfg->timeout_ms >= 0) { + size_t timeout_ticks = pdMS_TO_TICKS(cfg->timeout_ms); + uint32_t expired = xTaskGetTickCount() - start; + if (expired >= timeout_ticks) { + esp_tls_conn_delete(tls); + ESP_LOGE(TAG, "Failed to open new connection in specified timeout"); + return NULL; + } } } return NULL; @@ -330,8 +348,9 @@ esp_tls_t *esp_tls_conn_new(const char *hostname, int hostlen, int port, const e int esp_tls_conn_new_sync(const char *hostname, int hostlen, int port, const esp_tls_cfg_t *cfg, esp_tls_t *tls) { - /* esp_tls_conn_new_sync() is a sync alternative to esp_tls_conn_new_async() with symetric function prototype + /* esp_tls_conn_new_sync() is a sync alternative to esp_tls_conn_new_async() with symmetric function prototype it is an alternative to esp_tls_conn_new() which is left for compatibility reasons */ + size_t start = xTaskGetTickCount(); while (1) { int ret = esp_tls_low_level_conn(hostname, hostlen, port, cfg, tls); if (ret == 1) { @@ -339,6 +358,14 @@ int esp_tls_conn_new_sync(const char *hostname, int hostlen, int port, const esp } else if (ret == -1) { ESP_LOGE(TAG, "Failed to open new connection"); return -1; + } else if (ret == 0 && cfg->timeout_ms >= 0) { + size_t timeout_ticks = pdMS_TO_TICKS(cfg->timeout_ms); + uint32_t expired = xTaskGetTickCount() - start; + if (expired >= timeout_ticks) { + ESP_LOGW(TAG, "Failed to open new connection in specified timeout"); + ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_ESP, ESP_ERR_ESP_TLS_CONNECTION_TIMEOUT); + return 0; + } } } return 0; @@ -384,6 +411,7 @@ esp_tls_t *esp_tls_conn_http_new(const char *url, const esp_tls_cfg_t *cfg) get_port(url, &u), cfg, tls) == 1) { return tls; } + esp_tls_conn_delete(tls); return NULL; } @@ -409,6 +437,7 @@ mbedtls_x509_crt *esp_tls_get_global_ca_store(void) return _esp_tls_get_global_ca_store(); } +#endif /* CONFIG_ESP_TLS_USING_MBEDTLS */ #ifdef CONFIG_ESP_TLS_SERVER /** * @brief Create a server side TLS/SSL connection @@ -425,13 +454,22 @@ void esp_tls_server_session_delete(esp_tls_t *tls) return _esp_tls_server_session_delete(tls); } #endif /* CONFIG_ESP_TLS_SERVER */ -#endif /* CONFIG_ESP_TLS_USING_MBEDTLS */ ssize_t esp_tls_get_bytes_avail(esp_tls_t *tls) { return _esp_tls_get_bytes_avail(tls); } +esp_err_t esp_tls_get_conn_sockfd(esp_tls_t *tls, int *sockfd) +{ + if (!tls || !sockfd) { + ESP_LOGE(TAG, "Invalid arguments passed"); + return ESP_ERR_INVALID_ARG; + } + *sockfd = tls->sockfd; + return ESP_OK; +} + esp_err_t esp_tls_get_and_clear_last_error(esp_tls_error_handle_t h, int *esp_tls_code, int *esp_tls_flags) { if (!h) { diff --git a/components/esp-tls/esp_tls.h b/components/esp-tls/esp_tls.h index bd93764e6..9f2267b47 100644 --- a/components/esp-tls/esp_tls.h +++ b/components/esp-tls/esp_tls.h @@ -54,6 +54,15 @@ extern "C" { #define ESP_ERR_MBEDTLS_PK_PARSE_KEY_FAILED (ESP_ERR_ESP_TLS_BASE + 0x0F) /*!< mbedtls api returned failed */ #define ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED (ESP_ERR_ESP_TLS_BASE + 0x10) /*!< mbedtls api returned failed */ #define ESP_ERR_MBEDTLS_SSL_CONF_PSK_FAILED (ESP_ERR_ESP_TLS_BASE + 0x11) /*!< mbedtls api returned failed */ +#define ESP_ERR_ESP_TLS_CONNECTION_TIMEOUT (ESP_ERR_ESP_TLS_BASE + 0x12) /*!< new connection in esp_tls_low_level_conn connection timeouted */ +#define ESP_ERR_WOLFSSL_SSL_SET_HOSTNAME_FAILED (ESP_ERR_ESP_TLS_BASE + 0x13) /*!< wolfSSL api returned error */ +#define ESP_ERR_WOLFSSL_SSL_CONF_ALPN_PROTOCOLS_FAILED (ESP_ERR_ESP_TLS_BASE + 0x14) /*!< wolfSSL api returned error */ +#define ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED (ESP_ERR_ESP_TLS_BASE + 0x15) /*!< wolfSSL api returned error */ +#define ESP_ERR_WOLFSSL_KEY_VERIFY_SETUP_FAILED (ESP_ERR_ESP_TLS_BASE + 0x16) /*!< wolfSSL api returned error */ +#define ESP_ERR_WOLFSSL_SSL_HANDSHAKE_FAILED (ESP_ERR_ESP_TLS_BASE + 0x17) /*!< wolfSSL api returned failed */ +#define ESP_ERR_WOLFSSL_CTX_SETUP_FAILED (ESP_ERR_ESP_TLS_BASE + 0x18) /*!< wolfSSL api returned failed */ +#define ESP_ERR_WOLFSSL_SSL_SETUP_FAILED (ESP_ERR_ESP_TLS_BASE + 0x19) /*!< wolfSSL api returned failed */ +#define ESP_ERR_WOLFSSL_SSL_WRITE_FAILED (ESP_ERR_ESP_TLS_BASE + 0x1A) /*!< wolfSSL api returned failed */ #ifdef CONFIG_ESP_TLS_USING_MBEDTLS #define ESP_TLS_ERR_SSL_WANT_READ MBEDTLS_ERR_SSL_WANT_READ @@ -101,8 +110,8 @@ typedef struct psk_key_hint { } psk_hint_key_t; /** - * @brief ESP-TLS configuration parameters - * + * @brief ESP-TLS configuration parameters + * * @note Note about format of certificates: * - This structure includes certificates of a Certificate Authority, of client or server as well * as private keys, which may be of PEM or DER format. In case of PEM format, the buffer must be @@ -112,17 +121,17 @@ typedef struct psk_key_hint { * - Variables names of certificates and private key buffers and sizes are defined as unions providing * backward compatibility for legacy *_pem_buf and *_pem_bytes names which suggested only PEM format * was supported. It is encouraged to use generic names such as cacert_buf and cacert_bytes. - */ + */ typedef struct esp_tls_cfg { const char **alpn_protos; /*!< Application protocols required for HTTP2. If HTTP2/ALPN support is required, a list - of protocols that should be negotiated. + of protocols that should be negotiated. The format is length followed by protocol - name. + name. For the most common cases the following is ok: const char **alpn_protos = { "h2", NULL }; - where 'h2' is the protocol name */ - + union { const unsigned char *cacert_buf; /*!< Certificate Authority's certificate in a buffer. Format may be PEM or DER, depending on mbedtls-support @@ -170,8 +179,8 @@ typedef struct esp_tls_cfg { unsigned int clientkey_password_len; /*!< String length of the password pointed to by clientkey_password */ - bool non_block; /*!< Configure non-blocking mode. If set to true the - underneath socket will be configured in non + bool non_block; /*!< Configure non-blocking mode. If set to true the + underneath socket will be configured in non blocking mode after tls session is established */ int timeout_ms; /*!< Network timeout in milliseconds */ @@ -188,6 +197,10 @@ typedef struct esp_tls_cfg { then PSK authentication is enabled with configured setup. Important note: the pointer must be valid for connection */ + esp_err_t (*crt_bundle_attach)(void *conf); + /*!< Function pointer to esp_crt_bundle_attach. Enables the use of certification + bundle for server verification, must be enabled in menuconfig */ + } esp_tls_cfg_t; #ifdef CONFIG_ESP_TLS_SERVER @@ -246,24 +259,24 @@ typedef struct esp_tls_cfg_server { #endif /* ! CONFIG_ESP_TLS_SERVER */ /** - * @brief ESP-TLS Connection Handle + * @brief ESP-TLS Connection Handle */ typedef struct esp_tls { #ifdef CONFIG_ESP_TLS_USING_MBEDTLS mbedtls_ssl_context ssl; /*!< TLS/SSL context */ - + mbedtls_entropy_context entropy; /*!< mbedTLS entropy context structure */ - + mbedtls_ctr_drbg_context ctr_drbg; /*!< mbedTLS ctr drbg context structure. - CTR_DRBG is deterministic random + CTR_DRBG is deterministic random bit generation based on AES-256 */ - - mbedtls_ssl_config conf; /*!< TLS/SSL configuration to be shared - between mbedtls_ssl_context + + mbedtls_ssl_config conf; /*!< TLS/SSL configuration to be shared + between mbedtls_ssl_context structures */ - + mbedtls_net_context server_fd; /*!< mbedTLS wrapper type for sockets */ - + mbedtls_x509_crt cacert; /*!< Container for the X.509 CA certificate */ mbedtls_x509_crt *cacert_ptr; /*!< Pointer to the cacert being used. */ @@ -283,10 +296,10 @@ typedef struct esp_tls { void *priv_ssl; #endif int sockfd; /*!< Underlying socket file descriptor. */ - + ssize_t (*_read)(struct esp_tls *tls, char *data, size_t datalen); /*!< Callback function for reading data from TLS/SSL connection. */ - + ssize_t (*_write)(struct esp_tls *tls, const char *data, size_t datalen); /*!< Callback function for writing data to TLS/SSL connection. */ @@ -358,7 +371,7 @@ esp_tls_t *esp_tls_conn_new(const char *hostname, int hostlen, int port, const e * @return * - -1 If connection establishment fails. * - 1 If connection establishment is successful. - * - 0 Reserved for connection state is in progress. + * - 0 If connection state is in progress. */ int esp_tls_conn_new_sync(const char *hostname, int hostlen, int port, const esp_tls_cfg_t *cfg, esp_tls_t *tls); @@ -366,7 +379,7 @@ int esp_tls_conn_new_sync(const char *hostname, int hostlen, int port, const esp * @brief Create a new blocking TLS/SSL connection with a given "HTTP" url * * The behaviour is same as esp_tls_conn_new() API. However this API accepts host's url. - * + * * @param[in] url url of host. * @param[in] cfg TLS configuration as esp_tls_cfg_t. If you wish to open * non-TLS connection, keep this NULL. For TLS connection, @@ -375,7 +388,7 @@ int esp_tls_conn_new_sync(const char *hostname, int hostlen, int port, const esp * @return pointer to esp_tls_t, or NULL if connection couldn't be opened. */ esp_tls_t *esp_tls_conn_http_new(const char *url, const esp_tls_cfg_t *cfg); - + /** * @brief Create a new non-blocking TLS/SSL connection * @@ -414,18 +427,18 @@ int esp_tls_conn_http_new_async(const char *url, const esp_tls_cfg_t *cfg, esp_t /** * @brief Write from buffer 'data' into specified tls connection. - * + * * @param[in] tls pointer to esp-tls as esp-tls handle. * @param[in] data Buffer from which data will be written. * @param[in] datalen Length of data buffer. - * - * @return - * - >0 if write operation was successful, the return value is the number - * of bytes actually written to the TLS/SSL connection. + * + * @return + * - >0 if write operation was successful, the return value is the number + * of bytes actually written to the TLS/SSL connection. * - 0 if write operation was not successful. The underlying * connection was closed. - * - <0 if write operation was not successful, because either an - * error occured or an action must be taken by the calling process. + * - <0 if write operation was not successful, because either an + * error occured or an action must be taken by the calling process. */ static inline ssize_t esp_tls_conn_write(esp_tls_t *tls, const void *data, size_t datalen) { @@ -434,10 +447,10 @@ static inline ssize_t esp_tls_conn_write(esp_tls_t *tls, const void *data, size_ /** * @brief Read from specified tls connection into the buffer 'data'. - * + * * @param[in] tls pointer to esp-tls as esp-tls handle. * @param[in] data Buffer to hold read data. - * @param[in] datalen Length of data buffer. + * @param[in] datalen Length of data buffer. * * @return * - >0 if read operation was successful, the return value is the number @@ -454,11 +467,11 @@ static inline ssize_t esp_tls_conn_read(esp_tls_t *tls, void *data, size_t data /** * @brief Close the TLS/SSL connection and free any allocated resources. - * + * * This function should be called to close each tls connection opened with esp_tls_conn_new() or - * esp_tls_conn_http_new() APIs. + * esp_tls_conn_http_new() APIs. * - * @param[in] tls pointer to esp-tls as esp-tls handle. + * @param[in] tls pointer to esp-tls as esp-tls handle. */ void esp_tls_conn_delete(esp_tls_t *tls); @@ -477,6 +490,18 @@ void esp_tls_conn_delete(esp_tls_t *tls); */ ssize_t esp_tls_get_bytes_avail(esp_tls_t *tls); +/** + * @brief Returns the connection socket file descriptor from esp_tls session + * + * @param[in] tls handle to esp_tls context + * + * @param[out] sockfd int pointer to sockfd value. + * + * @return - ESP_OK on success and value of sockfd will be updated with socket file descriptor for connection + * - ESP_ERR_INVALID_ARG if (tls == NULL || sockfd == NULL) + */ +esp_err_t esp_tls_get_conn_sockfd(esp_tls_t *tls, int *sockfd); + /** * @brief Create a global CA store, initially empty. * @@ -549,6 +574,7 @@ esp_err_t esp_tls_get_and_clear_last_error(esp_tls_error_handle_t h, int *esp_tl */ mbedtls_x509_crt *esp_tls_get_global_ca_store(void); +#endif /* CONFIG_ESP_TLS_USING_MBEDTLS */ #ifdef CONFIG_ESP_TLS_SERVER /** * @brief Create TLS/SSL server session @@ -576,7 +602,6 @@ int esp_tls_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp_tls */ void esp_tls_server_session_delete(esp_tls_t *tls); #endif /* ! CONFIG_ESP_TLS_SERVER */ -#endif /* CONFIG_ESP_TLS_USING_MBEDTLS */ #ifdef __cplusplus } diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index 823fa6dbf..52c9daabd 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -26,6 +26,11 @@ #include #include "esp_log.h" +#ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE +#include "esp_crt_bundle.h" +#endif + + static const char *TAG = "esp-tls-mbedtls"; static mbedtls_x509_crt *global_cacert = NULL; @@ -266,7 +271,7 @@ static esp_err_t set_pki_context(esp_tls_t *tls, const esp_tls_pki_t *pki) } ret = mbedtls_pk_parse_key(pki->pk_key, pki->privkey_pem_buf, pki->privkey_pem_bytes, - NULL, 0); + pki->privkey_password, pki->privkey_password_len); if (ret < 0) { ESP_LOGE(TAG, "mbedtls_pk_parse_keyfile returned -0x%x", -ret); ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_MBEDTLS, -ret); @@ -389,16 +394,30 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t return ESP_ERR_MBEDTLS_SSL_CONFIG_DEFAULTS_FAILED; } -#ifdef CONFIG_MBEDTLS_SSL_ALPN + if (cfg->alpn_protos) { +#ifdef CONFIG_MBEDTLS_SSL_ALPN if ((ret = mbedtls_ssl_conf_alpn_protocols(&tls->conf, cfg->alpn_protos) != 0)) { ESP_LOGE(TAG, "mbedtls_ssl_conf_alpn_protocols returned -0x%x", -ret); ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_MBEDTLS, -ret); return ESP_ERR_MBEDTLS_SSL_CONF_ALPN_PROTOCOLS_FAILED; } +#else + ESP_LOGE(TAG, "alpn_protos configured but not enabled in menuconfig: Please enable MBEDTLS_SSL_ALPN option"); + return ESP_ERR_INVALID_STATE; +#endif } + + if (cfg->crt_bundle_attach != NULL) { +#ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE + ESP_LOGD(TAG, "Use certificate bundle"); + mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_REQUIRED); + cfg->crt_bundle_attach(&tls->conf); +#else //CONFIG_MBEDTLS_CERTIFICATE_BUNDLE + ESP_LOGE(TAG, "use_crt_bundle configured but not enabled in menuconfig: Please enable MBEDTLS_CERTIFICATE_BUNDLE option"); + return ESP_ERR_INVALID_STATE; #endif - if (cfg->use_global_ca_store == true) { + } else if (cfg->use_global_ca_store == true) { esp_err_t esp_ret = set_global_ca_store(tls); if (esp_ret != ESP_OK) { return esp_ret; @@ -470,8 +489,8 @@ int esp_mbedtls_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp tls->conn_state = ESP_TLS_FAIL; return -1; } - tls->read = esp_mbedtls_read; - tls->write = esp_mbedtls_write; + tls->_read = esp_mbedtls_read; + tls->_write = esp_mbedtls_write; int ret; while ((ret = mbedtls_ssl_handshake(&tls->ssl)) != 0) { if (ret != ESP_TLS_ERR_SSL_WANT_READ && ret != ESP_TLS_ERR_SSL_WANT_WRITE) { diff --git a/components/esp-tls/esp_tls_wolfssl.c b/components/esp-tls/esp_tls_wolfssl.c index 351ae0713..08ea8b5d0 100644 --- a/components/esp-tls/esp_tls_wolfssl.c +++ b/components/esp-tls/esp_tls_wolfssl.c @@ -31,16 +31,86 @@ static unsigned char *global_cacert = NULL; static unsigned int global_cacert_pem_bytes = 0; static const char *TAG = "esp-tls-wolfssl"; -int esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg1, esp_tls_t *tls) +/* Prototypes for the static functions */ +static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t *cfg, esp_tls_t *tls); + +#if defined(CONFIG_ESP_TLS_PSK_VERIFICATION) +#include "freertos/semphr.h" +static SemaphoreHandle_t tls_conn_lock; +static inline unsigned int esp_wolfssl_psk_client_cb(WOLFSSL* ssl, const char* hint, char* identity, + unsigned int id_max_len, unsigned char* key,unsigned int key_max_len); +static esp_err_t esp_wolfssl_set_cipher_list(WOLFSSL_CTX *ctx); +#ifdef WOLFSSL_TLS13 +#define PSK_MAX_ID_LEN 128 +#else +#define PSK_MAX_ID_LEN 64 +#endif +#define PSK_MAX_KEY_LEN 64 + +static char psk_id_str[PSK_MAX_ID_LEN]; +static uint8_t psk_key_array[PSK_MAX_KEY_LEN]; +static uint8_t psk_key_max_len = 0; +#endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */ + +#ifdef CONFIG_ESP_TLS_SERVER +static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls); +#endif /* CONFIG_ESP_TLS_SERVER */ + +typedef enum x509_file_type { + FILE_TYPE_CA_CERT = 0, /* CA certificate to authenticate entity at other end */ + FILE_TYPE_SELF_CERT, /* Self certificate of the entity */ + FILE_TYPE_SELF_KEY, /* Private key in the self cert-key pair */ +} x509_file_type_t; + +/* Checks whether the certificate provided is in pem format or not */ +static esp_err_t esp_load_wolfssl_verify_buffer(esp_tls_t *tls, const unsigned char *cert_buf, unsigned int cert_len, x509_file_type_t type, int *err_ret) +{ + int wolf_fileformat = WOLFSSL_FILETYPE_DEFAULT; + if (type == FILE_TYPE_SELF_KEY) { + if (cert_buf[cert_len - 1] == '\0' && strstr( (const char *) cert_buf, "-----BEGIN " )) { + wolf_fileformat = WOLFSSL_FILETYPE_PEM; + } else { + wolf_fileformat = WOLFSSL_FILETYPE_ASN1; + } + if ((*err_ret = wolfSSL_CTX_use_PrivateKey_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cert_buf, cert_len, wolf_fileformat)) == WOLFSSL_SUCCESS) { + return ESP_OK; + } + return ESP_FAIL; + } else { + if (cert_buf[cert_len - 1] == '\0' && strstr( (const char *) cert_buf, "-----BEGIN CERTIFICATE-----" )) { + wolf_fileformat = WOLFSSL_FILETYPE_PEM; + } else { + wolf_fileformat = WOLFSSL_FILETYPE_ASN1; + } + if (type == FILE_TYPE_SELF_CERT) { + if ((*err_ret = wolfSSL_CTX_use_certificate_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cert_buf, cert_len, wolf_fileformat)) == WOLFSSL_SUCCESS) { + return ESP_OK; + } + return ESP_FAIL; + } else if (type == FILE_TYPE_CA_CERT) { + if ((*err_ret = wolfSSL_CTX_load_verify_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cert_buf, cert_len, wolf_fileformat)) == WOLFSSL_SUCCESS) { + return ESP_OK; + } + return ESP_FAIL; + } else { + /* Wrong file type provided */ + return ESP_FAIL; + } + } +} + +esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls) { #ifdef CONFIG_ESP_DEBUG_WOLFSSL wolfSSL_Debugging_ON(); #endif - const esp_tls_cfg_t *cfg = cfg1; + assert(cfg != NULL); assert(tls != NULL); + esp_err_t esp_ret = ESP_FAIL; int ret; + ret = wolfSSL_Init(); if (ret != WOLFSSL_SUCCESS) { ESP_LOGE(TAG, "Init wolfSSL failed: %d", ret); @@ -48,70 +118,207 @@ int esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void * goto exit; } + if (tls->role == ESP_TLS_CLIENT) { + esp_ret = set_client_config(hostname, hostlen, (esp_tls_cfg_t *)cfg, tls); + if (esp_ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to set client configurations"); + goto exit; + } + } else if (tls->role == ESP_TLS_SERVER) { +#ifdef CONFIG_ESP_TLS_SERVER + esp_ret = set_server_config((esp_tls_cfg_server_t *) cfg, tls); + if (esp_ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to set server configurations"); + goto exit; + } +#else + ESP_LOGE(TAG, "ESP_TLS_SERVER Not enabled in menuconfig"); + goto exit; +#endif + } + else { + ESP_LOGE(TAG, "tls->role is not valid"); + goto exit; + } + + return ESP_OK; +exit: + esp_wolfssl_cleanup(tls); + return esp_ret; +} + +static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t *cfg, esp_tls_t *tls) +{ + int ret = WOLFSSL_FAILURE; tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_2_client_method()); if (!tls->priv_ctx) { ESP_LOGE(TAG, "Set wolfSSL ctx failed"); ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_WOLFSSL, -ret); - goto exit; + return ESP_ERR_WOLFSSL_CTX_SETUP_FAILED; + } + + if (cfg->use_global_ca_store == true) { + if ((esp_load_wolfssl_verify_buffer(tls, global_cacert, global_cacert_pem_bytes, FILE_TYPE_CA_CERT, &ret)) != ESP_OK) { + ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d", ret); + return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED; + } + wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER, NULL); + } else if (cfg->cacert_buf != NULL) { + if ((esp_load_wolfssl_verify_buffer(tls, cfg->cacert_buf, cfg->cacert_bytes, FILE_TYPE_CA_CERT, &ret)) != ESP_OK) { + ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d", ret); + return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED; + } + wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER, NULL); + } else if (cfg->psk_hint_key) { +#if defined(CONFIG_ESP_TLS_PSK_VERIFICATION) + /*** PSK encryption mode is configured only if no certificate supplied and psk pointer not null ***/ + if(cfg->psk_hint_key->key == NULL || cfg->psk_hint_key->hint == NULL || cfg->psk_hint_key->key_size <= 0) { + ESP_LOGE(TAG, "Please provide appropriate key, keysize and hint to use PSK"); + return ESP_FAIL; + } + /* mutex is given back when call back function executes or in case of failure (at cleanup) */ + if ((xSemaphoreTake(tls_conn_lock, 1000/portTICK_PERIOD_MS) != pdTRUE)) { + ESP_LOGE(TAG, "tls_conn_lock could not be obtained in specified time"); + return -1; + } + ESP_LOGI(TAG, "setting psk configurations"); + if((cfg->psk_hint_key->key_size > PSK_MAX_KEY_LEN) || (strlen(cfg->psk_hint_key->hint) > PSK_MAX_ID_LEN)) { + ESP_LOGE(TAG, "psk key length should be <= %d and identity hint length should be <= %d", PSK_MAX_KEY_LEN, PSK_MAX_ID_LEN); + return ESP_ERR_INVALID_ARG; + } + psk_key_max_len = cfg->psk_hint_key->key_size; + memset(psk_key_array, 0, sizeof(psk_key_array)); + memset(psk_id_str, 0, sizeof(psk_id_str)); + memcpy(psk_key_array, cfg->psk_hint_key->key, psk_key_max_len); + memcpy(psk_id_str, cfg->psk_hint_key->hint, strlen(cfg->psk_hint_key->hint)); + wolfSSL_CTX_set_psk_client_callback( (WOLFSSL_CTX *)tls->priv_ctx, esp_wolfssl_psk_client_cb); + if(esp_wolfssl_set_cipher_list( (WOLFSSL_CTX *)tls->priv_ctx) != ESP_OK) { + ESP_LOGE(TAG, "error in setting cipher-list"); + return ESP_FAIL; + } +#else + ESP_LOGE(TAG, "psk_hint_key configured but not enabled in menuconfig: Please enable ESP_TLS_PSK_VERIFICATION option"); + return ESP_ERR_INVALID_STATE; +#endif + } else { + wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_NONE, NULL); + } + + if (cfg->clientcert_buf != NULL && cfg->clientkey_buf != NULL) { + if ((esp_load_wolfssl_verify_buffer(tls,cfg->clientcert_buf, cfg->clientcert_bytes, FILE_TYPE_SELF_CERT, &ret)) != ESP_OK) { + ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d", ret); + return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED; + } + if ((esp_load_wolfssl_verify_buffer(tls,cfg->clientkey_buf, cfg->clientkey_bytes, FILE_TYPE_SELF_KEY, &ret)) != ESP_OK) { + ESP_LOGE(TAG, "Error in loading private key verify buffer, returned %d", ret); + return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED; + } + } else if (cfg->clientcert_buf != NULL || cfg->clientkey_buf != NULL) { + ESP_LOGE(TAG, "You have to provide both clientcert_buf and clientkey_buf for mutual authentication\n\n"); + return ESP_FAIL; + } + + if (cfg->crt_bundle_attach != NULL) { + ESP_LOGE(TAG,"use_crt_bundle not supported in wolfssl"); + return ESP_FAIL; + } + + tls->priv_ssl =(void *)wolfSSL_new( (WOLFSSL_CTX *)tls->priv_ctx); + if (!tls->priv_ssl) { + ESP_LOGE(TAG, "Create wolfSSL failed"); + ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_WOLFSSL, -ret); + return ESP_ERR_WOLFSSL_SSL_SETUP_FAILED; + } + + if (!cfg->skip_common_name) { +#ifdef HAVE_SNI + char *use_host = NULL; + if (cfg->common_name != NULL) { + use_host = strdup(cfg->common_name); + } else { + use_host = strndup(hostname, hostlen); + } + if (use_host == NULL) { + return ESP_ERR_NO_MEM; + } + /* Hostname set here should match CN in server certificate */ + if ((ret = wolfSSL_set_tlsext_host_name( (WOLFSSL *)tls->priv_ssl, use_host))!= WOLFSSL_SUCCESS) { + ESP_LOGE(TAG, "wolfSSL_set_tlsext_host_name returned -0x%x", -ret); + ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_WOLFSSL, -ret); + free(use_host); + return ESP_ERR_WOLFSSL_SSL_SET_HOSTNAME_FAILED; + } + free(use_host); +#endif /* HAVE_SNI */ } -#ifdef HAVE_ALPN if (cfg->alpn_protos) { +#ifdef CONFIG_WOLFSSL_HAVE_ALPN char **alpn_list = (char **)cfg->alpn_protos; for (; *alpn_list != NULL; alpn_list ++) { - if (wolfSSL_UseALPN( (WOLFSSL *)tls->priv_ssl, *alpn_list, strlen(*alpn_list), WOLFSSL_ALPN_FAILED_ON_MISMATCH) != WOLFSSL_SUCCESS) { + ESP_LOGD(TAG, "alpn protocol is %s", *alpn_list); + if ((ret = wolfSSL_UseALPN( (WOLFSSL *)tls->priv_ssl, *alpn_list, strlen(*alpn_list), WOLFSSL_ALPN_FAILED_ON_MISMATCH)) != WOLFSSL_SUCCESS) { ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_WOLFSSL, -ret); - ESP_LOGE(TAG, "Use wolfSSL ALPN failed"); - goto exit; + ESP_LOGE(TAG, "wolfSSL UseALPN failed, returned %d", ret); + return ESP_ERR_WOLFSSL_SSL_CONF_ALPN_PROTOCOLS_FAILED; } } +#else + ESP_LOGE(TAG, "CONFIG_WOLFSSL_HAVE_ALPN not enabled in menuconfig"); + return ESP_FAIL; +#endif /* CONFIG_WOLFSSL_HAVE_ALPN */ } -#endif - if ( cfg->use_global_ca_store == true) { - wolfSSL_CTX_load_verify_buffer( (WOLFSSL_CTX *)tls->priv_ctx, global_cacert, global_cacert_pem_bytes, WOLFSSL_FILETYPE_PEM); - wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, SSL_VERIFY_PEER, NULL); - } else if (cfg->cacert_pem_buf != NULL) { - wolfSSL_CTX_load_verify_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cfg->cacert_pem_buf, cfg->cacert_pem_bytes, WOLFSSL_FILETYPE_PEM); - wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, SSL_VERIFY_PEER, NULL); - } else if (cfg->psk_hint_key) { - ESP_LOGE(TAG,"psk_hint_key not supported in wolfssl"); - goto exit; + wolfSSL_set_fd((WOLFSSL *)tls->priv_ssl, tls->sockfd); + return ESP_OK; +} + +#ifdef CONFIG_ESP_TLS_SERVER +static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls) +{ + int ret = WOLFSSL_FAILURE; + tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_2_server_method()); + if (!tls->priv_ctx) { + ESP_LOGE(TAG, "Set wolfSSL ctx failed"); + return ESP_ERR_WOLFSSL_CTX_SETUP_FAILED; + } + + if (cfg->cacert_buf != NULL) { + if ((esp_load_wolfssl_verify_buffer(tls,cfg->cacert_buf, cfg->cacert_bytes, FILE_TYPE_CA_CERT, &ret)) != ESP_OK) { + ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d", ret); + return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED; + } + wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); + ESP_LOGD(TAG," Verify Client for Mutual Auth"); } else { - wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, SSL_VERIFY_NONE, NULL); + ESP_LOGD(TAG," Not verifying Client "); + wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_NONE, NULL); } - if (cfg->clientcert_pem_buf != NULL && cfg->clientkey_pem_buf != NULL) { - wolfSSL_CTX_use_certificate_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cfg->clientcert_pem_buf, cfg->clientcert_pem_bytes, WOLFSSL_FILETYPE_PEM); - wolfSSL_CTX_use_PrivateKey_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cfg->clientkey_pem_buf, cfg->clientkey_pem_bytes, WOLFSSL_FILETYPE_PEM); - } else if (cfg->clientcert_pem_buf != NULL || cfg->clientkey_pem_buf != NULL) { - ESP_LOGE(TAG, "You have to provide both clientcert_pem_buf and clientkey_pem_buf for mutual authentication\n\n"); - goto exit; + if (cfg->servercert_buf != NULL && cfg->serverkey_buf != NULL) { + if ((esp_load_wolfssl_verify_buffer(tls,cfg->servercert_buf, cfg->servercert_bytes, FILE_TYPE_SELF_CERT, &ret)) != ESP_OK) { + ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d", ret); + return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED; + } + if ((esp_load_wolfssl_verify_buffer(tls,cfg->serverkey_buf, cfg->serverkey_bytes, FILE_TYPE_SELF_KEY, &ret)) != ESP_OK) { + ESP_LOGE(TAG, "Error in loading private key verify buffer, returned %d", ret); + return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED; + } + } else { + ESP_LOGE(TAG, "You have to provide both servercert_buf and serverkey_buf for https_server\n\n"); + return ESP_FAIL; } tls->priv_ssl =(void *)wolfSSL_new( (WOLFSSL_CTX *)tls->priv_ctx); if (!tls->priv_ssl) { ESP_LOGE(TAG, "Create wolfSSL failed"); - ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_WOLFSSL, -ret); - goto exit; + return ESP_ERR_WOLFSSL_SSL_SETUP_FAILED; } -#ifdef HAVE_SNI - /* Hostname set here should match CN in server certificate */ - char *use_host = strndup(hostname, hostlen); - if (!use_host) { - goto exit; - } - wolfSSL_set_tlsext_host_name( (WOLFSSL *)tls->priv_ssl, use_host); - free(use_host); -#endif - wolfSSL_set_fd((WOLFSSL *)tls->priv_ssl, tls->sockfd); - return 0; -exit: - esp_wolfssl_cleanup(tls); - return ret; + return ESP_OK; } +#endif int esp_wolfssl_handshake(esp_tls_t *tls, const esp_tls_cfg_t *cfg) { @@ -125,8 +332,8 @@ int esp_wolfssl_handshake(esp_tls_t *tls, const esp_tls_cfg_t *cfg) if (err != ESP_TLS_ERR_SSL_WANT_READ && err != ESP_TLS_ERR_SSL_WANT_WRITE) { ESP_LOGE(TAG, "wolfSSL_connect returned -0x%x", -ret); ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_WOLFSSL, -ret); - - if (cfg->cacert_pem_buf != NULL || cfg->use_global_ca_store == true) { + ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_ESP, ESP_ERR_WOLFSSL_SSL_HANDSHAKE_FAILED); + if (cfg->cacert_buf != NULL || cfg->use_global_ca_store == true) { /* This is to check whether handshake failed due to invalid certificate*/ esp_wolfssl_verify_certificate(tls); } @@ -164,7 +371,9 @@ ssize_t esp_wolfssl_write(esp_tls_t *tls, const char *data, size_t datalen) ret = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret); if (ret != ESP_TLS_ERR_SSL_WANT_READ && ret != ESP_TLS_ERR_SSL_WANT_WRITE) { ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_WOLFSSL, -ret); + ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_ESP, ESP_ERR_WOLFSSL_SSL_WRITE_FAILED); ESP_LOGE(TAG, "write error :%d:", ret); + } } return ret; @@ -174,7 +383,7 @@ void esp_wolfssl_verify_certificate(esp_tls_t *tls) { int flags; if ((flags = wolfSSL_get_verify_result( (WOLFSSL *)tls->priv_ssl)) != WOLFSSL_SUCCESS) { - ESP_LOGE(TAG, "Failed to verify peer certificate %d!", flags); + ESP_LOGE(TAG, "Failed to verify peer certificate , returned %d!", flags); ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_WOLFSSL_CERT_FLAGS, flags); } else { ESP_LOGI(TAG, "Certificate verified."); @@ -202,12 +411,61 @@ void esp_wolfssl_cleanup(esp_tls_t *tls) if (!tls) { return; } +#ifdef CONFIG_ESP_TLS_PSK_VERIFICATION + xSemaphoreGive(tls_conn_lock); +#endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */ wolfSSL_shutdown( (WOLFSSL *)tls->priv_ssl); wolfSSL_free( (WOLFSSL *)tls->priv_ssl); + tls->priv_ssl = NULL; wolfSSL_CTX_free( (WOLFSSL_CTX *)tls->priv_ctx); + tls->priv_ctx = NULL; wolfSSL_Cleanup(); } +#ifdef CONFIG_ESP_TLS_SERVER +/** + * @brief Create TLS/SSL server session + */ +int esp_wolfssl_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp_tls_t *tls) +{ + if (tls == NULL || cfg == NULL) { + return -1; + } + tls->role = ESP_TLS_SERVER; + tls->sockfd = sockfd; + esp_err_t esp_ret = esp_create_wolfssl_handle(NULL, 0, cfg, tls); + if (esp_ret != ESP_OK) { + ESP_LOGE(TAG, "create_ssl_handle failed"); + ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_ESP, esp_ret); + tls->conn_state = ESP_TLS_FAIL; + return -1; + } + tls->_read = esp_wolfssl_read; + tls->_write = esp_wolfssl_write; + int ret; + while ((ret = wolfSSL_accept((WOLFSSL *)tls->priv_ssl)) != WOLFSSL_SUCCESS) { + if (ret != ESP_TLS_ERR_SSL_WANT_READ && ret != ESP_TLS_ERR_SSL_WANT_WRITE) { + ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_WOLFSSL, -ret); + ESP_LOGE(TAG, "wolfSSL_handshake_server returned %d", ret); + tls->conn_state = ESP_TLS_FAIL; + return ret; + } + } + return 0; +} + +/** + * @brief Close the server side TLS/SSL connection and free any allocated resources. + */ +void esp_wolfssl_server_session_delete(esp_tls_t *tls) +{ + if (tls != NULL) { + esp_wolfssl_cleanup(tls); + free(tls); + } +} +#endif /* CONFIG_ESP_TLS_SERVER */ + esp_err_t esp_wolfssl_init_global_ca_store(void) { /* This function is just to provide consistancy between function calls of esp_tls.h and wolfssl */ @@ -242,3 +500,56 @@ void esp_wolfssl_free_global_ca_store(void) global_cacert_pem_bytes = 0; } } + +#if defined(CONFIG_ESP_TLS_PSK_VERIFICATION) +static esp_err_t esp_wolfssl_set_cipher_list(WOLFSSL_CTX *ctx) +{ + const char *defaultCipherList; + int ret; +#if defined(HAVE_AESGCM) && !defined(NO_DH) +#ifdef WOLFSSL_TLS13 + defaultCipherList = "DHE-PSK-AES128-GCM-SHA256:" + "TLS13-AES128-GCM-SHA256"; +#else + defaultCipherList = "DHE-PSK-AES128-GCM-SHA256"; +#endif +#elif defined(HAVE_NULL_CIPHER) + defaultCipherList = "PSK-NULL-SHA256"; +#else + defaultCipherList = "PSK-AES128-CBC-SHA256"; +#endif + ESP_LOGD(TAG, "cipher list is %s", defaultCipherList); + if ((ret = wolfSSL_CTX_set_cipher_list(ctx,defaultCipherList)) != WOLFSSL_SUCCESS) { + wolfSSL_CTX_free(ctx); + ESP_LOGE(TAG, "can't set cipher list, returned %02x", ret); + return ESP_FAIL; + } + return ESP_OK; +} + +/* initialize the mutex before app_main() when using PSK */ +static void __attribute__((constructor)) +espt_tls_wolfssl_init_conn_lock (void) +{ + if ((tls_conn_lock = xSemaphoreCreateMutex()) == NULL) { + ESP_EARLY_LOGE(TAG, "mutex for tls psk connection could not be created"); + } +} + +/* Some callback functions required by PSK */ +static inline unsigned int esp_wolfssl_psk_client_cb(WOLFSSL* ssl, const char* hint, + char* identity, unsigned int id_max_len, unsigned char* key, + unsigned int key_max_len) +{ + (void)key_max_len; + + /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */ + memcpy(identity, psk_id_str, id_max_len); + for(int count = 0; count < psk_key_max_len; count ++) { + key[count] = psk_key_array[count]; + } + xSemaphoreGive(tls_conn_lock); + return psk_key_max_len; + /* return length of key in octets or 0 or for error */ +} +#endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */ diff --git a/components/esp-tls/private_include/esp_tls_wolfssl.h b/components/esp-tls/private_include/esp_tls_wolfssl.h index 73cb9f2f9..a04ad796c 100644 --- a/components/esp-tls/private_include/esp_tls_wolfssl.h +++ b/components/esp-tls/private_include/esp_tls_wolfssl.h @@ -70,3 +70,17 @@ void esp_wolfssl_free_global_ca_store(void); * Callback function for Initializing the global ca store for TLS?SSL using wolfssl */ esp_err_t esp_wolfssl_init_global_ca_store(void); + +#ifdef CONFIG_ESP_TLS_SERVER + +/** + * Function to Create ESP-TLS Server session with wolfssl Stack + */ +int esp_wolfssl_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp_tls_t *tls); + +/* + * Delete Server Session + */ +void esp_wolfssl_server_session_delete(esp_tls_t *tls); + +#endif diff --git a/components/esp-wolfssl/CMakeLists.txt b/components/esp-wolfssl/CMakeLists.txt index a215a5898..6f9488af9 100644 --- a/components/esp-wolfssl/CMakeLists.txt +++ b/components/esp-wolfssl/CMakeLists.txt @@ -9,8 +9,13 @@ endif() register_component() if(CONFIG_ESP_WOLFSSL_INTERNAL) -target_compile_options(${COMPONENT_NAME} PUBLIC -DWOLFSSL_USER_SETTINGS) +target_compile_options(${COMPONENT_LIB} PUBLIC -DWOLFSSL_USER_SETTINGS) -target_link_libraries(${COMPONENT_NAME} "-L ${CMAKE_CURRENT_SOURCE_DIR}/wolfssl/lib") -target_link_libraries(${COMPONENT_NAME} wolfssl) +target_link_libraries(${COMPONENT_LIB} PUBLIC "-L ${CMAKE_CURRENT_SOURCE_DIR}/wolfssl/lib") + +if(CONFIG_WOLFSSL_DEBUG) +target_link_libraries(${COMPONENT_LIB} PUBLIC "wolfssl_debug") +else() +target_link_libraries(${COMPONENT_LIB} PUBLIC "wolfssl") +endif() endif() diff --git a/components/esp8266/CMakeLists.txt b/components/esp8266/CMakeLists.txt index f66fd36bb..c1e4dbef9 100644 --- a/components/esp8266/CMakeLists.txt +++ b/components/esp8266/CMakeLists.txt @@ -108,23 +108,26 @@ else() add_custom_target(esp8266_linker_script DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/esp8266_out.ld") add_dependencies(${COMPONENT_LIB} esp8266_linker_script) - if(CONFIG_ESP8266_PHY_INIT_DATA_IN_PARTITION) - set(PHY_INIT_DATA_BIN phy_init_data.bin) + if(CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION) + set(PHY_INIT_DATA_BIN ${build_dir}/phy_init_data.bin) # To get the phy_init_data.bin file, compile phy_init_data.h as a C file and then objcopy # the object file to a raw binary add_custom_command( OUTPUT ${PHY_INIT_DATA_BIN} - DEPENDS ${CMAKE_CURRENT_LIST_DIR}/phy_init_data.h + DEPENDS ${CMAKE_CURRENT_LIST_DIR}/include/internal/phy_init_data.h COMMAND ${CMAKE_C_COMPILER} -x c -c -I ${CMAKE_CURRENT_LIST_DIR} -I ${CMAKE_CURRENT_LIST_DIR}/include -I ${CMAKE_BINARY_DIR} + -I ${CONFIG_DIR} -I ${CMAKE_CURRENT_LIST_DIR}/../esp_common/include -o phy_init_data.obj - ${CMAKE_CURRENT_LIST_DIR}/phy_init_data.h + ${CMAKE_CURRENT_LIST_DIR}/include/internal/phy_init_data.h COMMAND ${CMAKE_OBJCOPY} -O binary phy_init_data.obj ${PHY_INIT_DATA_BIN} ) add_custom_target(phy_init_data ALL DEPENDS ${PHY_INIT_DATA_BIN}) add_dependencies(flash phy_init_data) + partition_table_get_partition_info(phy_init_data_offset "--partition-type data --partition-subtype phy" "offset") + esptool_py_flash_project_args(phy_init_data ${phy_init_data_offset} "${PHY_INIT_DATA_BIN}" FLASH_IN_PROJECT) endif() if(CONFIG_ESP_FILENAME_MACRO_NO_PATH) diff --git a/components/esp8266/Kconfig b/components/esp8266/Kconfig index f1dcd4ebb..4b4ef6267 100644 --- a/components/esp8266/Kconfig +++ b/components/esp8266/Kconfig @@ -328,6 +328,18 @@ config ESP_ERR_TO_NAME_LOOKUP endchoice endmenu +menu "Power Management" + config PM_ENABLE + bool "Support for power management" + default n + help + If enabled, application is compiled with support for power management. + This option has run-time overhead (increased interrupt latency, + longer time to enter idle state), and it also reduces accuracy of + RTOS ticks and timers used for timekeeping. + Enable this option if application uses power management APIs. +endmenu + menu Wi-Fi config SCAN_AP_MAX @@ -391,7 +403,7 @@ config ESP8266_WIFI_RX_BUFFER_NUM config ESP8266_WIFI_LEFT_CONTINUOUS_RX_BUFFER_NUM int "The min number of WiFi continuous RX buffer" range 0 16 - default 4 + default 8 help Set the number of WiFi continuous RX buffer num. The smaller the value, the easier RX hang will appear. Most of time we should NOT change the default @@ -420,7 +432,7 @@ config ESP8266_WIFI_NVS_ENABLED Select this option to enable WiFi NVS flash config ESP8266_WIFI_CONNECT_OPEN_ROUTER_WHEN_PWD_IS_SET - bool "Connent open router when wifi password is set" + bool "Connect open router when wifi password is set" default y help When this option is enabled, ESP8266 will connect to open router even if wifi password is set, otherwise diff --git a/components/esp8266/driver/gpio.c b/components/esp8266/driver/gpio.c index 460cd6f22..a0124f669 100644 --- a/components/esp8266/driver/gpio.c +++ b/components/esp8266/driver/gpio.c @@ -86,7 +86,10 @@ static gpio_isr_func_t *gpio_isr_func = NULL; esp_err_t gpio_pullup_en(gpio_num_t gpio_num) { GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); - GPIO_CHECK(!RTC_GPIO_IS_VALID_GPIO(gpio_num), "The RTC GPIO of esp8266 can not be pulled up.", ESP_ERR_INVALID_ARG); + + if (RTC_GPIO_IS_VALID_GPIO(gpio_num)) { + return ESP_OK; + } gpio_pin_reg_t pin_reg; pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(gpio_num)); @@ -98,7 +101,10 @@ esp_err_t gpio_pullup_en(gpio_num_t gpio_num) esp_err_t gpio_pullup_dis(gpio_num_t gpio_num) { GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); - GPIO_CHECK(!RTC_GPIO_IS_VALID_GPIO(gpio_num), "The RTC GPIO of esp8266 can not be pulled up.", ESP_ERR_INVALID_ARG); + + if (RTC_GPIO_IS_VALID_GPIO(gpio_num)) { + return ESP_OK; + } gpio_pin_reg_t pin_reg; pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(gpio_num)); @@ -110,7 +116,10 @@ esp_err_t gpio_pullup_dis(gpio_num_t gpio_num) esp_err_t gpio_pulldown_en(gpio_num_t gpio_num) { GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); - GPIO_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "The GPIO of esp8266 can not be pulled down except RTC GPIO.", ESP_ERR_INVALID_ARG); + + if (!RTC_GPIO_IS_VALID_GPIO(gpio_num)) { + return ESP_OK; + } gpio_pin_reg_t pin_reg; pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(gpio_num)); @@ -122,7 +131,10 @@ esp_err_t gpio_pulldown_en(gpio_num_t gpio_num) esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num) { GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); - GPIO_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "The GPIO of esp8266 can not be pulled down except RTC GPIO.", ESP_ERR_INVALID_ARG); + + if (!RTC_GPIO_IS_VALID_GPIO(gpio_num)) { + return ESP_OK; + } gpio_pin_reg_t pin_reg; pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(gpio_num)); diff --git a/components/esp8266/driver/i2s.c b/components/esp8266/driver/i2s.c index 1de17aa91..8b4ea75f5 100644 --- a/components/esp8266/driver/i2s.c +++ b/components/esp8266/driver/i2s.c @@ -48,30 +48,6 @@ static const char *I2S_TAG = "i2s"; #define dma_intr_disable() _xt_isr_mask(1 << ETS_SLC_INUM) #define dma_intr_register(a, b) _xt_isr_attach(ETS_SLC_INUM, (a), (b)) -// Define them here if we can't find them. -#ifndef i2c_bbpll -#define i2c_bbpll 0x67 -#define i2c_bbpll_en_audio_clock_out 4 -#define i2c_bbpll_en_audio_clock_out_msb 7 -#define i2c_bbpll_en_audio_clock_out_lsb 7 -#define i2c_bbpll_hostid 4 - -/* ROM functions which read/write internal control bus */ -uint8_t rom_i2c_readReg(uint8_t block, uint8_t host_id, uint8_t reg_add); -uint8_t rom_i2c_readReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb); -void rom_i2c_writeReg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data); -void rom_i2c_writeReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data); - -#define i2c_writeReg_Mask(block, host_id, reg_add, Msb, Lsb, indata) rom_i2c_writeReg_Mask(block, host_id, reg_add, Msb, Lsb, indata) -#define i2c_readReg_Mask(block, host_id, reg_add, Msb, Lsb) rom_i2c_readReg_Mask(block, host_id, reg_add, Msb, Lsb) -#define i2c_writeReg_Mask_def(block, reg_add, indata) \ - i2c_writeReg_Mask(block, block##_hostid, reg_add, reg_add##_msb, reg_add##_lsb, indata) -#define i2c_readReg_Mask_def(block, reg_add) \ - i2c_readReg_Mask(block, block##_hostid, reg_add, reg_add##_msb, reg_add##_lsb) -#endif -#define I2S_CLK_ENABLE() i2c_writeReg_Mask_def(i2c_bbpll, i2c_bbpll_en_audio_clock_out, 1) -#define I2S_CLK_DISABLE() i2c_writeReg_Mask_def(i2c_bbpll, i2c_bbpll_en_audio_clock_out, 0) - #define I2S_MAX_BUFFER_SIZE (4 * 1024 * 1024) // the maximum RAM can be allocated #define I2S_BASE_CLK (2 * APB_CLK_FREQ) #define I2S_ENTER_CRITICAL() portENTER_CRITICAL() @@ -864,8 +840,6 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num) heap_caps_free(p_i2s_obj[i2s_num]); p_i2s_obj[i2s_num] = NULL; - I2S_CLK_DISABLE(); - return ESP_OK; } @@ -894,7 +868,6 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config, //initial interrupt dma_intr_register(i2s_intr_handler_default, p_i2s_obj[i2s_num]); - I2S_CLK_ENABLE(); i2s_stop(i2s_num); err = i2s_param_config(i2s_num, i2s_config); diff --git a/components/esp8266/driver/ledc.c b/components/esp8266/driver/ledc.c index 14169d08e..4b1ab64c7 100644 --- a/components/esp8266/driver/ledc.c +++ b/components/esp8266/driver/ledc.c @@ -203,7 +203,6 @@ esp_err_t ledc_fade_up(ledc_channel_t channel, uint8_t* flag) p_ledc_obj[channel]->duty_p += duty_value; } pwm_set_duty(channel, p_ledc_obj[channel]->duty_p); - pwm_start(); i[channel]++; if (i[channel] == 100) { i[channel] = 0; @@ -235,7 +234,6 @@ esp_err_t ledc_fade_down(ledc_channel_t channel, uint8_t* flag) p_ledc_obj[channel]->duty_p -= duty_value; } pwm_set_duty(channel, p_ledc_obj[channel]->duty_p); - pwm_start(); i[channel]++; if (i[channel] == 100) { i[channel] = 0; @@ -270,6 +268,7 @@ static void ledc_task(void* pvParameters) } } } + pwm_start(); xTaskResumeAll(); vTaskDelay(LEDC_STEP_TIME / portTICK_PERIOD_MS); } diff --git a/components/esp8266/driver/uart.c b/components/esp8266/driver/uart.c index 728c84589..3fc91f240 100644 --- a/components/esp8266/driver/uart.c +++ b/components/esp8266/driver/uart.c @@ -419,6 +419,11 @@ esp_err_t uart_isr_register(uart_port_t uart_num, void (*fn)(void *), void *arg) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG); + for (int num = 0; num < UART_NUM_MAX; num++) { + if (p_uart_obj[num] == NULL) { + uart_disable_intr_mask(num, UART_INTR_MASK); + } + } UART_ENTER_CRITICAL(); _xt_isr_mask(1 << ETS_UART_INUM); _xt_isr_attach(ETS_UART_INUM, uart_intr_service, NULL); @@ -587,7 +592,11 @@ static void uart_rx_intr_handler_default(void *param) } if (p_uart->tx_len_tot == 0) { - en_tx_flg = false; + if (tx_fifo_rem == 0) { + en_tx_flg = true; + } else{ + en_tx_flg = false; + } xSemaphoreGiveFromISR(p_uart->tx_done_sem, &task_woken); if (task_woken == pdTRUE) { portYIELD_FROM_ISR(); diff --git a/components/esp8266/include/driver/rtc.h b/components/esp8266/include/driver/rtc.h index 7715014c1..b9adc9c15 100644 --- a/components/esp8266/include/driver/rtc.h +++ b/components/esp8266/include/driver/rtc.h @@ -55,6 +55,11 @@ void rtc_init_clk(uint8_t *init_param); */ void rtc_lightsleep_init(void); +/** + * @brief Configure CPU sleep mode + */ +void pm_set_sleep_mode(uint32_t mode); + /** * @brief Initialize hardware when CPU wakes up from light sleep */ @@ -104,7 +109,7 @@ uint32_t rtc_light_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt); * * @return number of clock cycles */ -uint32_t pm_usec2rtc(uint32_t time_in_us, uint32_t period); +uint32_t rtc_us_to_clk(uint32_t time_in_us, uint32_t period); /** * @brief Convert time interval from RTC_CLK to microseconds @@ -114,7 +119,7 @@ uint32_t pm_usec2rtc(uint32_t time_in_us, uint32_t period); * * @return time interval in microseconds */ -uint32_t pm_rtc2usec(uint32_t rtc_cycles, uint32_t period); +uint32_t rtc_clk_to_us(uint32_t rtc_cycles, uint32_t period); /** * @brief Get the calibration value of RTC clock diff --git a/components/esp8266/include/esp8266/eagle_soc.h b/components/esp8266/include/esp8266/eagle_soc.h index d4351db63..11e5901ef 100644 --- a/components/esp8266/include/esp8266/eagle_soc.h +++ b/components/esp8266/include/esp8266/eagle_soc.h @@ -131,6 +131,7 @@ //}} //Interrupt remap control registers define{{ +#define NMI_INT_ENABLE_REG (PERIPHS_DPORT_BASEADDR) #define EDGE_INT_ENABLE_REG (PERIPHS_DPORT_BASEADDR + 0x04) #define WDT_EDGE_INT_ENABLE() SET_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT0) #define TM1_EDGE_INT_ENABLE() SET_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1) diff --git a/components/esp8266/include/esp8266/i2s_register.h b/components/esp8266/include/esp8266/i2s_register.h index a08b7b768..6e0a9c552 100644 --- a/components/esp8266/include/esp8266/i2s_register.h +++ b/components/esp8266/include/esp8266/i2s_register.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef _SLC_REGISTER_H_ -#define _SLC_REGISTER_H_ +#ifndef _I2S_REGISTER_H_ +#define _I2S_REGISTER_H_ #include "eagle_soc.h" diff --git a/components/esp8266/include/esp_event.h b/components/esp8266/include/esp_event.h index c3d8e75af..6c496e4ae 100644 --- a/components/esp8266/include/esp_event.h +++ b/components/esp8266/include/esp_event.h @@ -129,6 +129,11 @@ typedef struct { uint8_t mac[6]; /**< MAC address of the station which send probe request */ } system_event_ap_probe_req_rx_t; +/** Event structure for IP_EVENT_AP_STAIPASSIGNED event */ +typedef struct { + ip4_addr_t ip; /*!< IP address which was assigned to the station */ +} system_event_ap_staipassigned_t; + typedef union { system_event_sta_connected_t connected; /**< ESP8266 station connected to AP */ system_event_sta_disconnected_t disconnected; /**< ESP8266 station disconnected to AP */ @@ -140,6 +145,7 @@ typedef union { system_event_ap_staconnected_t sta_connected; /**< a station connected to ESP8266 soft-AP */ system_event_ap_stadisconnected_t sta_disconnected; /**< a station disconnected to ESP8266 soft-AP */ system_event_ap_probe_req_rx_t ap_probereqrecved; /**< ESP8266 soft-AP receive probe request packet */ + system_event_ap_staipassigned_t ap_staipassigned; /**< ESP8266 soft-AP assign an IP to the station*/ system_event_got_ip6_t got_ip6; /**< ESP8266 station or ap or ethernet ipv6 addr state change to preferred */ } system_event_info_t; diff --git a/components/esp8266/include/esp_sleep.h b/components/esp8266/include/esp_sleep.h index e877c7dff..d5c1a33e3 100644 --- a/components/esp8266/include/esp_sleep.h +++ b/components/esp8266/include/esp_sleep.h @@ -46,7 +46,7 @@ typedef enum { } esp_sleep_source_t; /** - * @brief Set the chip to deep-sleep mode. + * @brief Enter deep-sleep mode. * * The device will automatically wake up after the deep-sleep time set * by the users. Upon waking up, the device boots up from user_init. @@ -56,6 +56,9 @@ typedef enum { * @attention 2. system_deep_sleep(0): there is no wake up timer; in order to wake * up, connect a GPIO to pin RST, the chip will wake up by a falling-edge * on pin RST + * @attention 3. esp_deep_sleep does not shut down WiFi and higher level protocol + * connections gracefully. Make sure esp_wifi_stop are called to close any + * connections and deinitialize the peripherals. * * @param time_in_us deep-sleep time, unit: microsecond * @@ -63,6 +66,15 @@ typedef enum { */ void esp_deep_sleep(uint32_t time_in_us); +/** + * @brief Set implementation-specific power management configuration + * @param config pointer to implementation-specific configuration structure (e.g. esp_pm_config_esp32) + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if the configuration values are not correct + * - ESP_ERR_NOT_SUPPORTED if certain combination of values is not supported. + */ +esp_err_t esp_pm_configure(const void* config); /** * @brief Call this API before esp_deep_sleep and esp_wifi_init to set the activity after the @@ -207,9 +219,12 @@ esp_err_t esp_sleep_enable_timer_wakeup(uint32_t time_in_us); /** * @brief Enter light sleep with the configured wakeup options * + * @attention esp_deep_sleep does not shut down WiFi and higher level protocol + * connections gracefully. Make sure esp_wifi_stop are called to close any + * connections and deinitialize the peripherals. * @return * - ESP_OK on success (returned after wakeup) - * - ESP_ERR_INVALID_STATE if WiFi or BT is not stopped + * - ESP_ERR_INVALID_STATE if WiFi is not stopped */ esp_err_t esp_light_sleep_start(void); diff --git a/components/esp8266/include/esp_wifi.h b/components/esp8266/include/esp_wifi.h index a8bde5175..e88deface 100644 --- a/components/esp8266/include/esp_wifi.h +++ b/components/esp8266/include/esp_wifi.h @@ -90,9 +90,6 @@ extern "C" { #define ESP_WIFI_PARAM_USE_NVS 0 -#define WIFI_PROTOCAL_11B 1 -#define WIFI_PROTOCAL_11G 2 -#define WIFI_PROTOCAL_11N 4 /** * @brief WiFi stack configuration parameters passed to esp_wifi_init call. */ @@ -156,15 +153,15 @@ typedef struct { .osi_funcs = NULL, \ .qos_enable = WIFI_QOS_ENABLED,\ .ampdu_rx_enable = WIFI_AMPDU_RX_ENABLED,\ - .rx_ampdu_buf_len = WIFI_AMPDU_RX_AMPDU_BUF_LEN,\ - .rx_ampdu_buf_num = WIFI_AMPDU_RX_AMPDU_BUF_NUM,\ - .amsdu_rx_enable = WIFI_AMSDU_RX_ENABLED,\ .rx_ba_win = WIFI_AMPDU_RX_BA_WIN,\ + .rx_ampdu_buf_num = WIFI_AMPDU_RX_AMPDU_BUF_NUM,\ + .rx_ampdu_buf_len = WIFI_AMPDU_RX_AMPDU_BUF_LEN,\ .rx_max_single_pkt_len = WIFI_RX_MAX_SINGLE_PKT_LEN,\ .rx_buf_len = WIFI_HW_RX_BUFFER_LEN,\ + .amsdu_rx_enable = WIFI_AMSDU_RX_ENABLED,\ .rx_buf_num = CONFIG_ESP8266_WIFI_RX_BUFFER_NUM,\ - .left_continuous_rx_buf_num = CONFIG_ESP8266_WIFI_LEFT_CONTINUOUS_RX_BUFFER_NUM,\ .rx_pkt_num = CONFIG_ESP8266_WIFI_RX_PKT_NUM,\ + .left_continuous_rx_buf_num = CONFIG_ESP8266_WIFI_LEFT_CONTINUOUS_RX_BUFFER_NUM,\ .tx_buf_num = CONFIG_ESP8266_WIFI_TX_PKT_NUM,\ .nvs_enable = WIFI_NVS_ENABLED,\ .nano_enable = 0,\ @@ -977,6 +974,16 @@ esp_err_t esp_wifi_get_event_mask(uint32_t *mask); */ esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void *buffer, int len, bool en_sys_seq); +/** + * @brief Operation system start check time and enter sleep + * + * @note This function is called by system, user should not call this + * + * @return + * - wifi state + */ +wifi_state_t esp_wifi_get_state(void); + #ifdef __cplusplus } #endif diff --git a/components/esp8266/include/esp_wifi_types.h b/components/esp8266/include/esp_wifi_types.h index 58fdb2b5c..0096dd7b6 100755 --- a/components/esp8266/include/esp_wifi_types.h +++ b/components/esp8266/include/esp_wifi_types.h @@ -182,12 +182,31 @@ typedef struct { wifi_auth_mode_t authmode; /**< The weakest authmode to accept in the fast scan mode */ } wifi_fast_scan_threshold_t; +typedef enum { + WIFI_STATE_DEINIT=0, + WIFI_STATE_INIT, + WIFI_STATE_START +}wifi_state_t; + typedef enum { WIFI_PS_NONE, /**< No power save */ - WIFI_PS_MAX_MODEM, /**< Maximum modem power saving. In this mode, station close cpu and RF in DTIM period */ - WIFI_PS_MIN_MODEM, /**< Minimum modem power saving. In this mode, station close RF in DTIM period */ + WIFI_PS_MIN_MODEM, /**< Minimum modem power saving. In this mode, station wakes up to receive beacon every DTIM period */ + WIFI_PS_MAX_MODEM, /**< Maximum modem power saving. In this mode, interval to receive beacons is determined by the listen_interval + parameter in wifi_sta_config_t. + Attention: Using this option may cause ping failures. Not recommended */ } wifi_ps_type_t; +/** + * @brief Power management config for ESP8266 + * + * Pass a pointer to this structure as an argument to esp_pm_configure function. + */ +typedef struct { + int max_freq_mhz; /*!< Not used in ESP8266 */ + int min_freq_mhz; /*!< Not used in ESP8266 */ + bool light_sleep_enable; /*!< Enter light sleep when no locks are taken */ +} esp_pm_config_esp8266_t; + #define WIFI_PS_MODEM WIFI_PS_MIN_MODEM /**< @deprecated Use WIFI_PS_MIN_MODEM or WIFI_PS_MAX_MODEM instead */ #define WIFI_PROTOCOL_11B 1 diff --git a/components/esp8266/include/internal/esp_wifi_internal.h b/components/esp8266/include/internal/esp_wifi_internal.h index 40c257255..2d91dbe5c 100644 --- a/components/esp8266/include/internal/esp_wifi_internal.h +++ b/components/esp8266/include/internal/esp_wifi_internal.h @@ -175,6 +175,33 @@ esp_err_t esp_wifi_internal_set_log_mod(uint32_t submodule); */ esp_err_t esp_wifi_internal_get_log(wifi_log_level_t *log_level, uint32_t *log_mod); +/** + * @brief Receive broadcast/multicast packet or not when WiFi in power save. + * + * @param enable receive broadcast/multicast packet when set to true. + */ +void esp_wifi_set_pm_recv_multi_data(bool enable); + +/** + * @brief Receive broadcast/multicast packet or not when WiFi in power save + * + * @return + * - true: receive broadcast/multicast packet or not when WiFi in power save + * - false: drop broadcast/multicast packet or not when WiFi in power save + */ +bool esp_wifi_get_pm_recv_multi_data(void); + +/** + * @brief Enable/Disable Wi-Fi send PLCP (with long option) + * + * @param enable Enable or Disable this option + * @param tx_with_long Send with long PLCP or not + * + * @return + * None + */ +void esp_wifi_set_11b_tx_plcp(bool enable, bool tx_with_long); + #ifdef __cplusplus } #endif diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index f3c64ab41..990c61a5c 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -1,11 +1,11 @@ gwen: - core: 27927af - net80211: b7de510 - pp: b7de510 - wpa: 27927af - espnow: 27927af - wps: 27927af - wpa2: 27927af + core: ad298f9 + net80211: 30169f1 + pp: 30169f1 + wpa: dd5b2b4 + espnow: dd5b2b4 + wps: 921fc88 + wpa2: dd5b2b4 smartconfig: 2.8.2 - phy: 1155.0 + phy: 1163.0 diff --git a/components/esp8266/lib/libcore.a b/components/esp8266/lib/libcore.a old mode 100644 new mode 100755 index 350865e9f..37b9d02c8 Binary files a/components/esp8266/lib/libcore.a and b/components/esp8266/lib/libcore.a differ diff --git a/components/esp8266/lib/libcore_dbg.a b/components/esp8266/lib/libcore_dbg.a old mode 100644 new mode 100755 index 146b8fef0..2425aaac8 Binary files a/components/esp8266/lib/libcore_dbg.a and b/components/esp8266/lib/libcore_dbg.a differ diff --git a/components/esp8266/lib/libespnow.a b/components/esp8266/lib/libespnow.a index af66c041e..574c62deb 100644 Binary files a/components/esp8266/lib/libespnow.a and b/components/esp8266/lib/libespnow.a differ diff --git a/components/esp8266/lib/libespnow_dbg.a b/components/esp8266/lib/libespnow_dbg.a index 5d657c333..914360a14 100644 Binary files a/components/esp8266/lib/libespnow_dbg.a and b/components/esp8266/lib/libespnow_dbg.a differ diff --git a/components/esp8266/lib/libnet80211.a b/components/esp8266/lib/libnet80211.a index be5bcbbee..747bc0c07 100644 Binary files a/components/esp8266/lib/libnet80211.a and b/components/esp8266/lib/libnet80211.a differ diff --git a/components/esp8266/lib/libnet80211_dbg.a b/components/esp8266/lib/libnet80211_dbg.a index 8049f519d..61504b7e9 100644 Binary files a/components/esp8266/lib/libnet80211_dbg.a and b/components/esp8266/lib/libnet80211_dbg.a differ diff --git a/components/esp8266/lib/libphy.a b/components/esp8266/lib/libphy.a index e9c9cef90..3113a722c 100755 Binary files a/components/esp8266/lib/libphy.a and b/components/esp8266/lib/libphy.a differ diff --git a/components/esp8266/lib/libpp.a b/components/esp8266/lib/libpp.a index 3d3ef4edc..adfc031aa 100644 Binary files a/components/esp8266/lib/libpp.a and b/components/esp8266/lib/libpp.a differ diff --git a/components/esp8266/lib/libpp_dbg.a b/components/esp8266/lib/libpp_dbg.a index 196a265ca..e3e9d8133 100644 Binary files a/components/esp8266/lib/libpp_dbg.a and b/components/esp8266/lib/libpp_dbg.a differ diff --git a/components/esp8266/lib/librtc.a b/components/esp8266/lib/librtc.a index b099d1f70..cfb64443c 100755 Binary files a/components/esp8266/lib/librtc.a and b/components/esp8266/lib/librtc.a differ diff --git a/components/esp8266/lib/libwpa.a b/components/esp8266/lib/libwpa.a index ca2b0ff5a..64c77bdbd 100644 Binary files a/components/esp8266/lib/libwpa.a and b/components/esp8266/lib/libwpa.a differ diff --git a/components/esp8266/lib/libwpa2.a b/components/esp8266/lib/libwpa2.a index 23947f689..792437430 100644 Binary files a/components/esp8266/lib/libwpa2.a and b/components/esp8266/lib/libwpa2.a differ diff --git a/components/esp8266/lib/libwpa2_dbg.a b/components/esp8266/lib/libwpa2_dbg.a index 82ffdcca0..6013355bd 100644 Binary files a/components/esp8266/lib/libwpa2_dbg.a and b/components/esp8266/lib/libwpa2_dbg.a differ diff --git a/components/esp8266/lib/libwpa_dbg.a b/components/esp8266/lib/libwpa_dbg.a index 997517c9a..32cb2aa37 100644 Binary files a/components/esp8266/lib/libwpa_dbg.a and b/components/esp8266/lib/libwpa_dbg.a differ diff --git a/components/esp8266/lib/libwps.a b/components/esp8266/lib/libwps.a index 93ea67090..7f9524a6e 100644 Binary files a/components/esp8266/lib/libwps.a and b/components/esp8266/lib/libwps.a differ diff --git a/components/esp8266/lib/libwps_dbg.a b/components/esp8266/lib/libwps_dbg.a index e1fbde878..16e71ab53 100644 Binary files a/components/esp8266/lib/libwps_dbg.a and b/components/esp8266/lib/libwps_dbg.a differ diff --git a/components/esp8266/source/esp_sleep.c b/components/esp8266/source/esp_sleep.c index 10231283a..bc3e7b377 100644 --- a/components/esp8266/source/esp_sleep.c +++ b/components/esp8266/source/esp_sleep.c @@ -18,10 +18,13 @@ #include "esp_log.h" #include "esp_system.h" #include "esp_sleep.h" +#include "esp_wifi.h" #include "FreeRTOS.h" #include "freertos/task.h" #include "driver/soc.h" +#include "driver/gpio.h" #include "esp8266/timer_struct.h" +#include "esp8266/gpio_struct.h" #include "esp8266/rom_functions.h" #include "driver/rtc.h" #include "rom/uart.h" @@ -37,10 +40,11 @@ #define FRC2_TICKS_PER_US (5) #define FRC2_TICKS_MAX (UINT32_MAX / 4) -#define SLEEP_MIN_TIME (1000) -#define SLEEP_PROC_TIME (4450) +#define SLEEP_PROC_TIME (2735) #define WAKEUP_EARLY_TICKS (264) // PLL and STAL wait ticks -#define MIN_SLEEP_US (SLEEP_MIN_TIME + SLEEP_PROC_TIME) +#define MIN_SLEEP_US (6500) +#define RTC_TICK_CAL (100) +#define RTC_TICK_OFF (1245 + RTC_TICK_CAL) #define TAG "esp8266_pm" @@ -51,8 +55,21 @@ typedef struct pm_soc_clk { uint32_t frc2_cnt; uint32_t wdev_cnt; + + uint32_t rtc_val; + uint32_t cal_period; + + uint32_t sleep_us; } pm_soc_clk_t; +typedef struct sleep_proc { + uint32_t sleep_us; // sleep microsecond + + uint32_t wait_int : 1; // wait interrupt + uint32_t check_mode : 1; // check sleep mode + uint32_t flush_uart : 1; // flush UART +} sleep_proc_t; + static uint16_t s_lock_cnt = 1; static esp_sleep_mode_t s_sleep_mode = ESP_CPU_WAIT; static uint32_t s_sleep_wakup_triggers; @@ -74,8 +91,20 @@ static inline void restore_local_wdev(uint32_t reg) REG_WRITE(INT_ENA_WDEV, reg); } +uint32_t rtc_clk_to_us(uint32_t rtc_cycles, uint32_t period) +{ + return (uint64_t)rtc_cycles * period / 4096; +} + +uint32_t rtc_us_to_clk(uint32_t us, uint32_t period) +{ + return (uint64_t)us * 4096 / period; +} + static inline void save_soc_clk(pm_soc_clk_t *clk) { + clk->rtc_val = REG_READ(RTC_SLP_CNT_VAL); + clk->ccount = soc_get_ccount(); clk->frc2_enable = REG_READ(FRC2_CTL) & FRC2_CNTL_ENABLE; @@ -96,24 +125,56 @@ static inline uint32_t min_sleep_us(pm_soc_clk_t *clk) const uint32_t frc2_sleep_ticks = REG_READ(FRC2_ALARM) - clk->frc2_cnt; const uint32_t frc2_sleep_us = frc2_sleep_ticks < FRC2_TICKS_MAX ? frc2_sleep_ticks / FRC2_TICKS_PER_US : 0; - return MIN(ccompare_sleep_us, frc2_sleep_us); + clk->sleep_us = MIN(ccompare_sleep_us, frc2_sleep_us); } else { - return ccompare_sleep_us; + clk->sleep_us = ccompare_sleep_us; } + + return clk->sleep_us; } -static inline void update_soc_clk(pm_soc_clk_t *clk, uint32_t us) +static inline uint32_t sleep_rtc_ticks(pm_soc_clk_t *clk) +{ + uint32_t rtc_ticks; + + clk->cal_period = pm_rtc_clock_cali_proc(); + + rtc_ticks = rtc_us_to_clk(clk->sleep_us - SLEEP_PROC_TIME, clk->cal_period); + + return rtc_ticks; +} + +static inline void update_soc_clk(pm_soc_clk_t *clk) { extern uint32_t WdevTimOffSet; - const uint32_t os_ccount = us * g_esp_ticks_per_us + clk->ccount; + uint32_t slept_us; + + if (s_sleep_wakup_triggers & RTC_GPIO_TRIG_EN) { + uint32_t total_rtc = 0, end_rtc = REG_READ(RTC_SLP_CNT_VAL); + + if (end_rtc > clk->rtc_val) + total_rtc = end_rtc - clk->rtc_val; + else + total_rtc = UINT32_MAX - clk->rtc_val + end_rtc; + slept_us = rtc_clk_to_us(total_rtc, clk->cal_period) + RTC_TICK_OFF; + + if (slept_us >= clk->sleep_us) + slept_us = clk->sleep_us; + else + slept_us -= RTC_TICK_CAL; + } else { + slept_us = clk->sleep_us; + } + + const uint32_t os_ccount = slept_us * g_esp_ticks_per_us + clk->ccount; if (os_ccount >= _xt_tick_divisor) soc_set_ccompare(os_ccount + 32); soc_set_ccount(os_ccount); if (clk->frc2_enable) { - const uint32_t frc2_cnt = us * FRC2_TICKS_PER_US + clk->frc2_cnt - 1; + const uint32_t frc2_cnt = slept_us * FRC2_TICKS_PER_US + clk->frc2_cnt - 1; REG_WRITE(FRC2_LOAD, frc2_cnt); } @@ -122,9 +183,9 @@ static inline void update_soc_clk(pm_soc_clk_t *clk, uint32_t us) uint32_t wdev_cnt = REG_READ(WDEV_COUNT_REG); if (clk->wdev_cnt < wdev_cnt) - wdev_us = us - (wdev_cnt - clk->wdev_cnt); + wdev_us = slept_us - (wdev_cnt - clk->wdev_cnt); else - wdev_us = us - (UINT32_MAX - clk->wdev_cnt + wdev_cnt); + wdev_us = slept_us - (UINT32_MAX - clk->wdev_cnt + wdev_cnt); WdevTimOffSet += wdev_us; } @@ -134,14 +195,30 @@ static int cpu_is_wait_mode(void) return (s_sleep_mode == ESP_CPU_WAIT) || s_lock_cnt; } -void esp_wifi_hw_open(void) +static int cpu_reject_sleep(void) { - phy_open_rf(); -} + int ret = 0; + + if (s_sleep_wakup_triggers & RTC_GPIO_TRIG_EN) { + for (int gpio = 0; gpio < 16; gpio++) { + if (!GPIO.pin[gpio].wakeup_enable) + continue; + + if (GPIO.pin[gpio].int_type == GPIO_INTR_LOW_LEVEL) { + if (!((GPIO.in >> gpio) & 1)) { + ret = 1; + break; + } + } else if (GPIO.pin[gpio].int_type == GPIO_INTR_HIGH_LEVEL) { + if ((GPIO.in >> gpio) & 1) { + ret = 1; + break; + } + } + } + } -void esp_wifi_hw_close(void) -{ - phy_close_rf(); + return ret; } rtc_cpu_freq_t rtc_clk_cpu_freq_get(void) @@ -170,7 +247,7 @@ esp_err_t esp_sleep_enable_timer_wakeup(uint32_t time_in_us) if (time_in_us <= MIN_SLEEP_US) return ESP_ERR_INVALID_ARG; - s_sleep_duration = time_in_us - SLEEP_PROC_TIME; + s_sleep_duration = time_in_us; s_sleep_wakup_triggers |= RTC_TIMER_TRIG_EN; return ESP_OK; @@ -203,35 +280,108 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source) return ESP_OK; } -esp_err_t esp_light_sleep_start(void) +static int esp_light_sleep_internal(const sleep_proc_t *proc) { - esp_err_t ret; - esp_irqflag_t irqflag = soc_save_local_irq(); - uint32_t wdevflag = save_local_wdev(); - uint32_t period = pm_rtc_clock_cali_proc(); - const uint32_t sleep_rtc_ticks = pm_usec2rtc(s_sleep_duration, period); + pm_soc_clk_t clk; + esp_irqflag_t irqflag; + uint32_t wdevflag; + uint32_t sleep_us; + uint64_t start_us; + int ret = ESP_OK; + int cpu_wait = proc->wait_int; + + start_us = esp_timer_get_time(); + + if (proc->check_mode && cpu_is_wait_mode()) { + if (proc->wait_int) + soc_wait_int(); + return ESP_ERR_INVALID_ARG; + } + + if (cpu_reject_sleep()) { + if (proc->wait_int) + soc_wait_int(); + return ESP_ERR_INVALID_STATE; + } - if (sleep_rtc_ticks > WAKEUP_EARLY_TICKS + 1) { - const rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get(); + if (proc->flush_uart) { + uart_tx_wait_idle(0); + uart_tx_wait_idle(1); + } - rtc_lightsleep_init(); - pm_set_sleep_cycles(sleep_rtc_ticks - WAKEUP_EARLY_TICKS); - rtc_light_sleep_start(s_sleep_wakup_triggers, 0); - rtc_wakeup_init(); + irqflag = soc_save_local_irq(); + wdevflag = save_local_wdev(); - rtc_clk_cpu_freq_set(cpu_freq); + if (proc->check_mode && cpu_is_wait_mode()) { + ret = ESP_ERR_INVALID_ARG; + goto exit; + } - ret = ESP_OK; - } else { + if (cpu_reject_sleep()) { ret = ESP_ERR_INVALID_STATE; + goto exit; + } + + save_soc_clk(&clk); + if (!proc->sleep_us) + sleep_us = min_sleep_us(&clk); + else { + uint64_t total_us = esp_timer_get_time() - start_us; + + if (total_us >= proc->sleep_us) { + ret = ESP_ERR_INVALID_ARG; + goto exit; + } else + sleep_us = clk.sleep_us = proc->sleep_us - total_us; } + if (sleep_us > MIN_SLEEP_US) { + uint32_t rtc_ticks = sleep_rtc_ticks(&clk); + + if (rtc_ticks > WAKEUP_EARLY_TICKS + 1) { + rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get(); + + pm_set_sleep_mode(2); + pm_set_sleep_cycles(rtc_ticks - WAKEUP_EARLY_TICKS); + rtc_light_sleep_start(s_sleep_wakup_triggers | RTC_TIMER_TRIG_EN, 0); + rtc_wakeup_init(); + + rtc_clk_cpu_freq_set(cpu_freq); + + update_soc_clk(&clk); + + cpu_wait = 0; + } else + ret = ESP_ERR_INVALID_ARG; + } else + ret = ESP_ERR_INVALID_ARG; + +exit: restore_local_wdev(wdevflag); soc_restore_local_irq(irqflag); + if (cpu_wait) + soc_wait_int(); + return ret; } +esp_err_t esp_light_sleep_start(void) +{ + const sleep_proc_t proc = { + .sleep_us = s_sleep_duration, + .wait_int = 0, + .check_mode = 0, + .flush_uart = 1 + }; + + if (esp_wifi_get_state() >= WIFI_STATE_START) { + return ESP_ERR_INVALID_STATE; + } + + return esp_light_sleep_internal(&proc); +} + void esp_sleep_lock(void) { const esp_irqflag_t irqflag = soc_save_local_irq(); @@ -253,51 +403,27 @@ void esp_sleep_set_mode(esp_sleep_mode_t mode) void esp_sleep_start(void) { - if (cpu_is_wait_mode()) { - soc_wait_int(); - return ; - } - - uart_tx_wait_idle(0); - uart_tx_wait_idle(1); - - int cpu_wait = 1; - pm_soc_clk_t clk; - const esp_irqflag_t irqflag = soc_save_local_irq(); - const uint32_t wdevflag = save_local_wdev(); - - if (cpu_is_wait_mode()) { - cpu_wait = 0; - goto exit; - } - - save_soc_clk(&clk); - - const uint32_t sleep_us = min_sleep_us(&clk); - if (sleep_us > MIN_SLEEP_US) { - uint32_t period = pm_rtc_clock_cali_proc(); - const uint32_t sleep_rtc_ticks = pm_usec2rtc(sleep_us - SLEEP_PROC_TIME, period); - - if (sleep_rtc_ticks > WAKEUP_EARLY_TICKS + 1) { - const rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get(); - - rtc_lightsleep_init(); - pm_set_sleep_cycles(sleep_rtc_ticks - WAKEUP_EARLY_TICKS); - rtc_light_sleep_start(s_sleep_wakup_triggers | RTC_TIMER_TRIG_EN, 0); - rtc_wakeup_init(); - - rtc_clk_cpu_freq_set(cpu_freq); + const sleep_proc_t proc = { + .sleep_us = 0, + .wait_int = 1, + .check_mode = 1, + .flush_uart = 1, + }; + + esp_light_sleep_internal(&proc); +} - update_soc_clk(&clk, sleep_us); +esp_err_t esp_pm_configure(const void* vconfig) +{ +#ifndef CONFIG_PM_ENABLE + return ESP_ERR_NOT_SUPPORTED; +#endif - cpu_wait = 0; - } + const esp_pm_config_esp8266_t* config = (const esp_pm_config_esp8266_t*) vconfig; + if (config->light_sleep_enable) { + s_sleep_mode = ESP_CPU_LIGHTSLEEP; + } else { + s_sleep_mode = ESP_CPU_WAIT; } - -exit: - restore_local_wdev(wdevflag); - soc_restore_local_irq(irqflag); - - if (cpu_wait) - soc_wait_int(); + return ESP_OK; } diff --git a/components/esp8266/source/esp_wifi.c b/components/esp8266/source/esp_wifi.c index 1cd45f4c5..e1ca2c7ea 100644 --- a/components/esp8266/source/esp_wifi.c +++ b/components/esp8266/source/esp_wifi.c @@ -20,7 +20,12 @@ #include "phy.h" const size_t _g_esp_wifi_ppt_task_stk_size = CONFIG_WIFI_PPT_TASKSTACK_SIZE; -const bool _g_esp_wifi_connect_open_router_when_pwd_is_set = CONFIG_ESP8266_WIFI_CONNECT_OPEN_ROUTER_WHEN_PWD_IS_SET; + +#if CONFIG_ESP8266_WIFI_CONNECT_OPEN_ROUTER_WHEN_PWD_IS_SET +const bool _g_esp_wifi_connect_open_router_when_pwd_is_set = true; +#else +const bool _g_esp_wifi_connect_open_router_when_pwd_is_set = false; +#endif esp_err_t esp_wifi_init_internal(const wifi_init_config_t *config); diff --git a/components/esp8266/source/startup.c b/components/esp8266/source/startup.c index 89ef3d815..786b4341b 100644 --- a/components/esp8266/source/startup.c +++ b/components/esp8266/source/startup.c @@ -71,6 +71,10 @@ static void user_init_entry(void *param) extern void app_main(void); + extern void phy_close_rf(void); + + extern void esp_sleep_unlock(); + /* initialize C++ construture function */ for (func = &__init_array_start; func < &__init_array_end; func++) func[0](); @@ -86,6 +90,8 @@ static void user_init_entry(void *param) assert(mac_init() == 0); assert(base_gpio_init() == 0); esp_phy_load_cal_and_init(0); + phy_close_rf(); + esp_sleep_unlock(); esp_wifi_set_rx_pbuf_mem_type(WIFI_RX_PBUF_DRAM); diff --git a/components/esp_http_client/lib/include/http_utils.h b/components/esp_http_client/lib/include/http_utils.h index d57840228..14c3b10c4 100644 --- a/components/esp_http_client/lib/include/http_utils.h +++ b/components/esp_http_client/lib/include/http_utils.h @@ -16,7 +16,7 @@ #ifndef _HTTP_UTILS_H_ #define _HTTP_UTILS_H_ #include -#include "esp_transport_utils.h" + /** * @brief Assign new_str to *str pointer, and realloc *str if it not NULL * @@ -80,7 +80,9 @@ char *http_utils_join_string(const char *first_str, int len_first, const char *s int http_utils_str_starts_with(const char *str, const char *start); -#define HTTP_MEM_CHECK(TAG, a, action) ESP_TRANSPORT_MEM_CHECK(TAG, a, action) - +#define HTTP_MEM_CHECK(TAG, a, action) if (!(a)) { \ + ESP_LOGE(TAG,"%s:%d (%s): %s", __FILE__, __LINE__, __FUNCTION__, "Memory exhausted"); \ + action; \ + } #endif diff --git a/components/freertos/freertos/queue.c b/components/freertos/freertos/queue.c index c37d285f3..a87d6d62e 100644 --- a/components/freertos/freertos/queue.c +++ b/components/freertos/freertos/queue.c @@ -360,6 +360,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; Queue_t *pxNewQueue; size_t xQueueSizeInBytes; uint8_t *pucQueueStorage; + BaseType_t overflow; configASSERT( uxQueueLength > ( UBaseType_t ) 0 ); @@ -375,7 +376,29 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ } - pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); + /* Check for multiplication overflow. */ + overflow = ( uxItemSize != 0 ) && ( uxQueueLength != ( xQueueSizeInBytes / uxItemSize ) ); + + /* Check for addition overflow. */ + overflow = overflow || ( ( sizeof( Queue_t ) + xQueueSizeInBytes ) < xQueueSizeInBytes ); + + if ( overflow == (BaseType_t) 0 ) + { + /* Allocate the queue and storage area. Justification for MISRA + deviation as follows: pvPortMalloc() always ensures returned memory + blocks are aligned per the requirements of the MCU stack. In this case + pvPortMalloc() must return a pointer that is guaranteed to meet the + alignment requirements of the Queue_t structure - which in this case + is an int8_t *. Therefore, whenever the stack alignment requirements + are greater than or equal to the pointer to char requirements the cast + is safe. In other cases alignment requirements are not strict (one or + two bytes). */ + pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); /*lint !e9087 !e9079 see comment above. */ + } + else + { + pxNewQueue = NULL; + } if( pxNewQueue != NULL ) { diff --git a/components/freertos/freertos/stream_buffer.c b/components/freertos/freertos/stream_buffer.c index c60045f69..317be2355 100644 --- a/components/freertos/freertos/stream_buffer.c +++ b/components/freertos/freertos/stream_buffer.c @@ -242,8 +242,15 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, this is a quirk of the implementation that means otherwise the free space would be reported as one byte smaller than would be logically expected. */ - xBufferSizeBytes++; - pucAllocatedMemory = ( uint8_t * ) pvPortMalloc( xBufferSizeBytes + sizeof( StreamBuffer_t ) ); /*lint !e9079 malloc() only returns void*. */ + if( xBufferSizeBytes < ( xBufferSizeBytes + 1 + sizeof( StreamBuffer_t ) ) ) + { + xBufferSizeBytes++; + pucAllocatedMemory = ( uint8_t * ) pvPortMalloc( xBufferSizeBytes + sizeof( StreamBuffer_t ) ); /*lint !e9079 malloc() only returns void*. */ + } + else + { + pucAllocatedMemory = NULL; + } if( pucAllocatedMemory != NULL ) { diff --git a/components/freertos/port/esp8266/panic.c b/components/freertos/port/esp8266/panic.c index 1c7db7f46..435cf65a5 100644 --- a/components/freertos/port/esp8266/panic.c +++ b/components/freertos/port/esp8266/panic.c @@ -125,17 +125,35 @@ static void panic_frame(panic_frame_t *frame) #endif /* ESP_PANIC_PRINT */ #ifdef ESP_PANIC_REBOOT +static void hardware_restart(void) +{ + CLEAR_WDT_REG_MASK(WDT_CTL_ADDRESS, BIT0); + WDT_REG_WRITE(WDT_OP_ADDRESS, 1); + WDT_REG_WRITE(WDT_OP_ND_ADDRESS, 1); + SET_PERI_REG_BITS(PERIPHS_WDT_BASEADDR + WDT_CTL_ADDRESS, + WDT_CTL_RSTLEN_MASK, + 7 << WDT_CTL_RSTLEN_LSB, + 0); + SET_PERI_REG_BITS(PERIPHS_WDT_BASEADDR + WDT_CTL_ADDRESS, + WDT_CTL_RSPMOD_MASK, + 0 << WDT_CTL_RSPMOD_LSB, + 0); + SET_PERI_REG_BITS(PERIPHS_WDT_BASEADDR + WDT_CTL_ADDRESS, + WDT_CTL_EN_MASK, + 1 << WDT_CTL_EN_LSB, + 0); +} + static void esp_panic_reset(void) { uart_tx_wait_idle(0); - uart_tx_wait_idle(1); - - rom_i2c_writeReg(0x67, 4, 1, 0x08); - rom_i2c_writeReg(0x67, 4, 2, 0x81); + uart_tx_wait_idle(1); esp_reset_reason_set_hint(ESP_RST_PANIC); - rom_software_reboot(); + hardware_restart(); + + while (1); } #endif diff --git a/components/freertos/port/esp8266/port.c b/components/freertos/port/esp8266/port.c index 2658e8929..91c7cdc03 100644 --- a/components/freertos/port/esp8266/port.c +++ b/components/freertos/port/esp8266/port.c @@ -281,23 +281,37 @@ void esp_dport_close_nmi(void) void IRAM_ATTR vPortETSIntrLock(void) { if (NMIIrqIsOn == 0) { + uint32_t regval = REG_READ(NMI_INT_ENABLE_REG); + vPortEnterCritical(); + + REG_WRITE(NMI_INT_ENABLE_REG, 0); + if (!ESP_NMI_IS_CLOSED()) { do { REG_WRITE(INT_ENA_WDEV, WDEV_TSF0_REACH_INT); } while(REG_READ(INT_ENA_WDEV) != WDEV_TSF0_REACH_INT); } + + REG_WRITE(NMI_INT_ENABLE_REG, regval); } } void IRAM_ATTR vPortETSIntrUnlock(void) { if (NMIIrqIsOn == 0) { + uint32_t regval = REG_READ(NMI_INT_ENABLE_REG); + + REG_WRITE(NMI_INT_ENABLE_REG, 0); + if (!ESP_NMI_IS_CLOSED()) { extern uint32_t WDEV_INTEREST_EVENT; REG_WRITE(INT_ENA_WDEV, WDEV_INTEREST_EVENT); } + + REG_WRITE(NMI_INT_ENABLE_REG, regval); + vPortExitCritical(); } } diff --git a/components/libsodium/Kconfig b/components/libsodium/Kconfig index a63a86c18..171ea55f1 100644 --- a/components/libsodium/Kconfig +++ b/components/libsodium/Kconfig @@ -3,7 +3,6 @@ menu "libsodium" config LIBSODIUM_USE_MBEDTLS_SHA bool "Use mbedTLS SHA256 & SHA512 implementations" default y - depends on !ESP_SHA help If this option is enabled, libsodium will use thin wrappers around mbedTLS for SHA256 & SHA512 operations. diff --git a/components/libsodium/port/crypto_hash_mbedtls/crypto_hash_sha256_mbedtls.c b/components/libsodium/port/crypto_hash_mbedtls/crypto_hash_sha256_mbedtls.c index 39c36c70a..960e2bda0 100644 --- a/components/libsodium/port/crypto_hash_mbedtls/crypto_hash_sha256_mbedtls.c +++ b/components/libsodium/port/crypto_hash_mbedtls/crypto_hash_sha256_mbedtls.c @@ -16,15 +16,6 @@ #include "mbedtls/sha256.h" #include -#ifdef MBEDTLS_SHA256_ALT -/* Wrapper only works if the libsodium context structure can be mapped - directly to the mbedTLS context structure. - - See extended comments in crypto_hash_sha512_mbedtls.c -*/ -#error "This wrapper only support standard software mbedTLS SHA" -#endif - /* Sanity check that all the context fields have identical sizes (this should be more or less given from the SHA256 algorithm) diff --git a/components/libsodium/port/crypto_hash_mbedtls/crypto_hash_sha512_mbedtls.c b/components/libsodium/port/crypto_hash_mbedtls/crypto_hash_sha512_mbedtls.c index 4dd58a1de..b005f0ce0 100644 --- a/components/libsodium/port/crypto_hash_mbedtls/crypto_hash_sha512_mbedtls.c +++ b/components/libsodium/port/crypto_hash_mbedtls/crypto_hash_sha512_mbedtls.c @@ -16,18 +16,6 @@ #include "mbedtls/sha512.h" #include -#ifdef MBEDTLS_SHA512_ALT -/* Wrapper only works if the libsodium context structure can be mapped - directly to the mbedTLS context structure. - - For ESP8266 hardware SHA, the problems are fitting all the data in - the libsodium state structure, and also that libsodium doesn't - have mbedtls_sha512_free() or mbedtls_sha512_clone() so we can't - manage the hardware state in a clean way. -*/ -#error "This wrapper only support standard software mbedTLS SHA" -#endif - /* Sanity check that all the context fields have identical sizes (this should be more or less given from the SHA512 algorithm) diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index 0006c0068..f957e325e 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -26,6 +26,12 @@ config LWIP_GLOBAL_DATA_LINK_IRAM help Link LWIP global data(.bss .data COMMON) from DRAM to IRAM. +config ESP_LWIP_RECV_REST_DATA + bool "Receive rest data although TCP aborts" + default n + help + Receive rest data although TCP aborts. + config TCPIP_RECVMBOX_SIZE int "TCPIP task receive mail box size" default 32 @@ -254,6 +260,12 @@ config LWIP_DHCP_DISCOVER_RETRANSMISSION_INTERVAL help Set time interval of retransmissions of DHCP discover. +config LWIP_ESP_DHCP_OPTION + bool "Enable DHCP option60 and option61 in discovery and request state" + default n + help + Maybe some routers need add those option to get IP address. + Enable this config to add option60 and option61 in discovery and request state endmenu #DHCP menuconfig LWIP_AUTOIP @@ -479,6 +491,13 @@ config LWIP_TCP_TIMESTAMPS really used locally. Therefore, it is only enabled when a TS option is received in the initial SYN packet from a remote host. +config LWIP_TCP_RTO_TIME + int "Default TCP RTO TIME" + default 1000 + help + Set default TCP RTO time for a reasonable initial RTO. + Advise to set initial RTO to 1 second + endmenu # TCP menu "UDP" diff --git a/components/lwip/apps/multi-threads/sockets_mt.c b/components/lwip/apps/multi-threads/sockets_mt.c index e339251aa..3e36221fc 100644 --- a/components/lwip/apps/multi-threads/sockets_mt.c +++ b/components/lwip/apps/multi-threads/sockets_mt.c @@ -494,14 +494,24 @@ static void lwip_sync_mt(int s, int how) extern void sys_arch_msleep(int ms); if (!_sock_get_select(s, SOCK_MT_SELECT_RECV | SOCK_MT_SELECT_SEND)) { + SOCK_MT_DEBUG(1, "lock state=%d how=%d\n", lock, how); + switch (lock) { case SOCK_MT_LOCK_SEND: - lwip_sync_state_mt(s); - need_wait = 1; + if (how == SHUT_WR || how == SHUT_RDWR) { + lwip_sync_state_mt(s); + need_wait = 1; + } else { + lock = _sock_next_lock(lock); + } break; case SOCK_MT_LOCK_RECV: - lwip_sync_recv_mt(s); - need_wait = 1; + if (how == SHUT_RD || how == SHUT_RDWR) { + lwip_sync_recv_mt(s); + need_wait = 1; + } else { + lock = _sock_next_lock(lock); + } break; default : break; @@ -769,7 +779,24 @@ int lwip_fcntl(int s, int cmd, int val) int lwip_shutdown(int s, int how) { - return 0; + int ret; + SYS_ARCH_DECL_PROTECT(lev); + + if (tryget_socket(s) == NULL) + return -1; + + SYS_ARCH_PROTECT(lev); + if (!_sock_is_opened(s)) { + SYS_ARCH_UNPROTECT(lev); + return -1; + } + SYS_ARCH_UNPROTECT(lev); + + lwip_sync_mt(s, how); + + ret = lwip_shutdown_esp(s, how); + + return ret; } int lwip_close(int s) diff --git a/components/lwip/lwip/src/api/api_lib.c b/components/lwip/lwip/src/api/api_lib.c index c428f32c8..32299610f 100644 --- a/components/lwip/lwip/src/api/api_lib.c +++ b/components/lwip/lwip/src/api/api_lib.c @@ -500,6 +500,9 @@ netconn_recv_data(struct netconn *conn, void **new_buf) #endif /* LWIP_TCP */ LWIP_ERROR("netconn_recv: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;); +#if ESP_LWIP_RECV_REST_DATA + if (!sys_mbox_valid(&conn->recvmbox)) { +#endif if (ERR_IS_FATAL(conn->last_err)) { /* don't recv on fatal errors: this might block the application task waiting on recvmbox forever! */ @@ -507,6 +510,9 @@ netconn_recv_data(struct netconn *conn, void **new_buf) before the fatal error occurred - is that a problem? */ return conn->last_err; } +#if ESP_LWIP_RECV_REST_DATA + } +#endif #if LWIP_TCP #if (LWIP_UDP || LWIP_RAW) if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) diff --git a/components/lwip/lwip/src/core/ipv4/dhcp.c b/components/lwip/lwip/src/core/ipv4/dhcp.c index a916c2ea6..60d96f287 100644 --- a/components/lwip/lwip/src/core/ipv4/dhcp.c +++ b/components/lwip/lwip/src/core/ipv4/dhcp.c @@ -209,6 +209,12 @@ static void dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif); /* always add the DHCP options trailer to end and pad */ static void dhcp_option_trailer(struct dhcp *dhcp); +#if ESP_DHCP_OPTION +/* set dhcp option61 */ +static void dhcp_option_clientid(struct dhcp *dhcp, struct netif *netif); +/* set dhcp option60 */ +static void dhcp_option_vendor(struct dhcp *dhcp, struct netif *netif); +#endif /** Ensure DHCP PCB is allocated and bound */ static err_t dhcp_inc_pcb_refcount(void) @@ -362,6 +368,10 @@ dhcp_select(struct netif *netif) /* create and initialize the DHCP message header */ result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); if (result == ERR_OK) { +#if ESP_DHCP_OPTION + dhcp_option_clientid(dhcp, netif); + dhcp_option_vendor(dhcp, netif); +#endif dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); @@ -518,6 +528,8 @@ dhcp_timeout(struct netif *netif) } else { dhcp_discover(netif); } + } else if (dhcp->state == DHCP_STATE_REBINDING) { + dhcp->t2_rebind_time = 1; } } @@ -978,6 +990,10 @@ dhcp_discover(struct netif *netif) if (result == ERR_OK) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n")); +#if ESP_DHCP_OPTION + dhcp_option_clientid(dhcp, netif); + dhcp_option_vendor(dhcp, netif); +#endif dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); @@ -985,6 +1001,11 @@ dhcp_discover(struct netif *netif) for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { dhcp_option_byte(dhcp, dhcp_discover_request_options[i]); } + +#if LWIP_NETIF_HOSTNAME + dhcp_option_hostname(dhcp, netif); +#endif /* LWIP_NETIF_HOSTNAME */ + dhcp_option_trailer(dhcp); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: realloc()ing\n")); @@ -1151,6 +1172,10 @@ dhcp_renew(struct netif *netif) /* create and initialize the DHCP message header */ result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); if (result == ERR_OK) { +#if ESP_DHCP_OPTION + dhcp_option_clientid(dhcp, netif); + dhcp_option_vendor(dhcp, netif); +#endif dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); @@ -1203,6 +1228,10 @@ dhcp_rebind(struct netif *netif) /* create and initialize the DHCP message header */ result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); if (result == ERR_OK) { +#if ESP_DHCP_OPTION + dhcp_option_clientid(dhcp, netif); + dhcp_option_vendor(dhcp, netif); +#endif dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); @@ -1253,6 +1282,10 @@ dhcp_reboot(struct netif *netif) /* create and initialize the DHCP message header */ result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); if (result == ERR_OK) { +#if ESP_DHCP_OPTION + dhcp_option_clientid(dhcp, netif); + dhcp_option_vendor(dhcp, netif); +#endif dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN_MIN_REQUIRED); @@ -1264,6 +1297,10 @@ dhcp_reboot(struct netif *netif) dhcp_option_byte(dhcp, dhcp_discover_request_options[i]); } +#if LWIP_NETIF_HOSTNAME + dhcp_option_hostname(dhcp, netif); +#endif /* LWIP_NETIF_HOSTNAME */ + dhcp_option_trailer(dhcp); pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); @@ -1461,6 +1498,76 @@ dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif) } #endif /* LWIP_NETIF_HOSTNAME */ +#if ESP_DHCP_OPTION +static void dhcp_option_clientid(struct dhcp *dhcp, struct netif *netif) +{ + if (netif) { + u8_t id_len = NETIF_MAX_HWADDR_LEN + 1; + dhcp_option(dhcp, DHCP_OPTION_CLIENT_ID, id_len); + dhcp_option_byte(dhcp, DHCP_HTYPE_ETH); + for (u8_t i = 0; i < NETIF_MAX_HWADDR_LEN; i++) { + dhcp_option_byte(dhcp, netif->hwaddr[i]); + } + } +} + +static u8_t vendor_class_len = 0; +static char *vendor_class_buf = NULL; +err_t dhcp_set_vendor_class_identifier(u8_t len, char *str) +{ + if (len == 0 || str == NULL) { + return ERR_ARG; + } + + if (vendor_class_buf) { + mem_free(vendor_class_buf); + vendor_class_buf = NULL; + } + + vendor_class_buf = (char *)mem_malloc(len + 1); + + if (vendor_class_buf == NULL) { + return ERR_MEM; + } + + vendor_class_len = len; + memcpy(vendor_class_buf, str, len); + return ERR_OK; +} + +static void dhcp_option_vendor(struct dhcp *dhcp, struct netif *netif) +{ + const char *p = NULL; + u8_t len = 0; + /* Shrink len to available bytes (need 2 bytes for OPTION_HOSTNAME + and 1 byte for trailer) */ + size_t available = DHCP_OPTIONS_LEN - dhcp->options_out_len - 3; + if (vendor_class_buf && vendor_class_len) { + p = vendor_class_buf; + LWIP_ASSERT("DHCP: vendor_class_len is too long!", vendor_class_len <= available); + len = vendor_class_len; + } else { //use hostname as vendor +#if LWIP_NETIF_HOSTNAME + if (netif->hostname != NULL) { + size_t namelen = strlen(netif->hostname); + if ((namelen > 0) && (namelen < 0xFF)) { + p = netif->hostname; + LWIP_ASSERT("DHCP: hostname is too long!", namelen <= available); + len = (u8_t) namelen; + } + } +#endif + } + + if (p) { + dhcp_option(dhcp, DHCP_OPTION_US, (u8_t)len); + while (len--) { + dhcp_option_byte(dhcp, *p++); + } + } +} +#endif + /** * Extract the DHCP message and the DHCP options. * diff --git a/components/lwip/lwip/src/core/ipv6/mld6.c b/components/lwip/lwip/src/core/ipv6/mld6.c index 9acb82fe2..bb7e1cab4 100644 --- a/components/lwip/lwip/src/core/ipv6/mld6.c +++ b/components/lwip/lwip/src/core/ipv6/mld6.c @@ -306,6 +306,10 @@ mld6_joingroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr) err_t err = ERR_VAL; /* no matching interface */ struct netif *netif; +#if ESP_LWIP + LWIP_ERROR("mld6_joingroup: attempt to join non-multicast address", ip6_addr_ismulticast(groupaddr), return ERR_VAL;); +#endif + /* loop through netif's */ netif = netif_list; while (netif != NULL) { diff --git a/components/lwip/lwip/src/core/tcp.c b/components/lwip/lwip/src/core/tcp.c index fba9d99e6..b10c6fcb3 100644 --- a/components/lwip/lwip/src/core/tcp.c +++ b/components/lwip/lwip/src/core/tcp.c @@ -1562,6 +1562,57 @@ tcp_kill_timewait(void) } } +#if ESP_LWIP +typedef struct { + u8_t time_wait; + u8_t closing; + u8_t fin_wait2; + u8_t last_ack; + u8_t fin_wait1; + u8_t listen; + u8_t bound; + u8_t total; +}tcp_pcb_num_t; +void tcp_pcb_num_cal(tcp_pcb_num_t *tcp_pcb_num); +void tcp_pcb_num_cal(tcp_pcb_num_t *tcp_pcb_num) +{ + struct tcp_pcb_listen *listen; + struct tcp_pcb *pcb; + + if (!tcp_pcb_num) { + return; + } + memset(tcp_pcb_num, 0, sizeof(*tcp_pcb_num)); + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + tcp_pcb_num->total ++; + tcp_pcb_num->time_wait ++; + } + + for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + tcp_pcb_num->total ++; + if (pcb->state == FIN_WAIT_2){ + tcp_pcb_num->fin_wait2 ++; + } else if (pcb->state == LAST_ACK) { + tcp_pcb_num->last_ack ++; + } else if (pcb->state == CLOSING) { + tcp_pcb_num->closing ++; + } else if (pcb->state == FIN_WAIT_1) { + tcp_pcb_num->fin_wait1 ++; + } + } + + for (listen = tcp_listen_pcbs.listen_pcbs; listen != NULL; listen = listen->next) { + tcp_pcb_num->total ++; + tcp_pcb_num->listen ++; + } + + for (pcb = tcp_bound_pcbs; pcb != NULL; pcb = pcb->next) { + tcp_pcb_num->total ++; + tcp_pcb_num->bound ++; + } +} +#endif + /** * Allocate a new tcp_pcb structure. * @@ -1572,7 +1623,34 @@ struct tcp_pcb * tcp_alloc(u8_t prio) { struct tcp_pcb *pcb; +#if ESP_LWIP + tcp_pcb_num_t tcp_pcb_num; + tcp_pcb_num_cal(&tcp_pcb_num); + if (tcp_pcb_num.total >= MEMP_NUM_TCP_PCB) { + if (tcp_pcb_num.time_wait > 0){ + tcp_kill_timewait(); + } else if (tcp_pcb_num.last_ack > 0){ + tcp_kill_state(LAST_ACK); + } else if (tcp_pcb_num.closing > 0){ + tcp_kill_state(CLOSING); + } else if (tcp_pcb_num.fin_wait2 > 0){ + tcp_kill_state(FIN_WAIT_2); + } else if (tcp_pcb_num.fin_wait1 > 0){ + tcp_kill_state(FIN_WAIT_1); + } else { + tcp_kill_prio(prio); + } + } + + tcp_pcb_num_cal(&tcp_pcb_num); + if (tcp_pcb_num.total >= MEMP_NUM_TCP_PCB){ + LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: no available tcp pcb %d %d %d %d %d %d %d %d\n", + tcp_pcb_num.total, tcp_pcb_num.time_wait, tcp_pcb_num.last_ack, tcp_pcb_num.closing, + tcp_pcb_num.fin_wait2, tcp_pcb_num.fin_wait1, tcp_pcb_num.listen, tcp_pcb_num.bound)); + return NULL; + } +#endif pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); if (pcb == NULL) { /* Try killing oldest connection in TIME-WAIT. */ @@ -1630,8 +1708,9 @@ tcp_alloc(u8_t prio) /* As initial send MSS, we use TCP_MSS but limit it to 536. The send MSS is updated when an MSS option is received. */ pcb->mss = INITIAL_MSS; - pcb->rto = 3000 / TCP_SLOW_INTERVAL; - pcb->sv = 3000 / TCP_SLOW_INTERVAL; + /* make TCP's retransmission time to be configurable */ + pcb->rto = LWIP_TCP_RTO_TIME / TCP_SLOW_INTERVAL; + pcb->sv = LWIP_TCP_RTO_TIME / TCP_SLOW_INTERVAL; pcb->rtime = -1; pcb->cwnd = 1; pcb->tmr = tcp_ticks; diff --git a/components/lwip/lwip/src/include/lwip/opt.h b/components/lwip/lwip/src/include/lwip/opt.h index 8f8b07771..634ae70b9 100644 --- a/components/lwip/lwip/src/include/lwip/opt.h +++ b/components/lwip/lwip/src/include/lwip/opt.h @@ -1350,6 +1350,11 @@ #define LWIP_WND_SCALE 0 #define TCP_RCV_SCALE 0 #endif + +#if !defined LWIP_TCP_RTO_TIME || defined __DOXYGEN__ +#define LWIP_TCP_RTO_TIME 3000 +#endif + /** * @} */ diff --git a/components/lwip/lwip/src/include/lwip/prot/dhcp.h b/components/lwip/lwip/src/include/lwip/prot/dhcp.h index 112953cb8..02ed51d0a 100644 --- a/components/lwip/lwip/src/include/lwip/prot/dhcp.h +++ b/components/lwip/lwip/src/include/lwip/prot/dhcp.h @@ -175,6 +175,9 @@ typedef enum { #define DHCP_OVERLOAD_SNAME 2 #define DHCP_OVERLOAD_SNAME_FILE 3 +#if ESP_DHCP_OPTION +err_t dhcp_set_vendor_class_identifier(u8_t len, char *str); +#endif #ifdef __cplusplus } diff --git a/components/lwip/lwip/src/include/posix/sys/socket.h b/components/lwip/lwip/src/include/posix/sys/socket.h index d6068709d..c9d142dcd 100644 --- a/components/lwip/lwip/src/include/posix/sys/socket.h +++ b/components/lwip/lwip/src/include/posix/sys/socket.h @@ -33,7 +33,8 @@ #include "sdkconfig.h" #include "lwip/sockets.h" - +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" #if !LWIP_POSIX_SOCKETS_IO_NAMES #include #include diff --git a/components/lwip/port/esp8266/include/lwipopts.h b/components/lwip/port/esp8266/include/lwipopts.h index 970ac342e..7fea63dbb 100644 --- a/components/lwip/port/esp8266/include/lwipopts.h +++ b/components/lwip/port/esp8266/include/lwipopts.h @@ -82,6 +82,12 @@ #define ESP_NONBLOCK 0 #endif +#ifdef CONFIG_ESP_LWIP_RECV_REST_DATA +#define ESP_LWIP_RECV_REST_DATA 1 +#else +#define ESP_LWIP_RECV_REST_DATA 0 +#endif + //#define SOCKETS_TCP_TRACE #define TCP_HIGH_SPEED_RETRANSMISSION CONFIG_TCP_HIGH_SPEED_RETRANSMISSION @@ -1097,6 +1103,12 @@ size_t memp_malloc_get_size(size_t type); */ #define LWIP_WND_SCALE 0 #define TCP_RCV_SCALE 0 + +/** + * LWIP_TCP_RTO_TIME: make TCP RTO time configurable. + * Default is 1 second. + */ +#define LWIP_TCP_RTO_TIME CONFIG_LWIP_TCP_RTO_TIME /** * @} */ @@ -2302,4 +2314,5 @@ void tcp_print_status(int status, void* p, uint32_t tmp1, uint32_t tmp2, uint32_ #define ESP_GRATUITOUS_ARP CONFIG_LWIP_ESP_GRATUITOUS_ARP #define ESP_PING 1 +#define ESP_DHCP_OPTION CONFIG_LWIP_ESP_DHCP_OPTION #endif /* __LWIP_HDR_LWIPOPTS_H__ */ diff --git a/components/lwip/port/esp8266/netif/ethernetif.c b/components/lwip/port/esp8266/netif/ethernetif.c index 18868cd0e..e6065c63d 100644 --- a/components/lwip/port/esp8266/netif/ethernetif.c +++ b/components/lwip/port/esp8266/netif/ethernetif.c @@ -299,6 +299,10 @@ static void low_level_init(struct netif* netif) netif->flags |= NETIF_FLAG_IGMP; #endif /* Do whatever else is needed to initialize interface. */ + +#if LWIP_IPV6_AUTOCONFIG + netif->ip6_autoconfig_enabled = 1; +#endif /* LWIP_IPV6_AUTOCONFIG */ } /* diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 20133beaf..9aebd1d96 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -19,8 +19,18 @@ set_property(TARGET mbedtls PROPERTY SOURCES ${src_tls}) set(mbedtls_targets mbedtls mbedcrypto mbedx509) # Add port files to mbedtls targets -target_sources(mbedtls PRIVATE "${COMPONENT_DIR}/port/mbedtls_debug.c" - "${COMPONENT_DIR}/port/net_sockets.c") +set(mbedtls_target_sources "${COMPONENT_DIR}/port/mbedtls_debug.c" + "${COMPONENT_DIR}/port/net_sockets.c") + +if(CONFIG_MBEDTLS_DYNAMIC_BUFFER) +set(mbedtls_target_sources ${mbedtls_target_sources} + "${COMPONENT_DIR}/port/dynamic/esp_mbedtls_dynamic_impl.c" + "${COMPONENT_DIR}/port/dynamic/esp_ssl_cli.c" + "${COMPONENT_DIR}/port/dynamic/esp_ssl_srv.c" + "${COMPONENT_DIR}/port/dynamic/esp_ssl_tls.c") +endif() + +target_sources(mbedtls PRIVATE ${mbedtls_target_sources}) target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c" "${COMPONENT_DIR}/port/esp_mem.c" @@ -30,9 +40,27 @@ target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c" "${COMPONENT_DIR}/port/esp8266/sha256.c" "${COMPONENT_DIR}/port/esp8266/sha512.c") + foreach(target ${mbedtls_targets}) target_compile_definitions(${target} PUBLIC -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h" -DCONFIG_SSL_USING_MBEDTLS) endforeach() +if(CONFIG_MBEDTLS_DYNAMIC_BUFFER) + set(WRAP_FUNCTIONS + mbedtls_ssl_handshake_client_step + mbedtls_ssl_handshake_server_step + mbedtls_ssl_read + mbedtls_ssl_write + mbedtls_ssl_session_reset + mbedtls_ssl_free + mbedtls_ssl_setup + mbedtls_ssl_send_alert_message + mbedtls_ssl_close_notify) + + foreach(wrap ${WRAP_FUNCTIONS}) + target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=${wrap}") + endforeach() +endif() + # Link mbedtls libraries to component library target_link_libraries(${COMPONENT_LIB} INTERFACE ${mbedtls_targets}) diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index a1c396cf2..10949c96a 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -81,6 +81,40 @@ menu "mbedTLS" This defines maximum outgoing fragment length, overriding default maximum content length (MBEDTLS_SSL_MAX_CONTENT_LEN). + config MBEDTLS_DYNAMIC_BUFFER + bool "Using dynamic TX/RX buffer" + default n + select MBEDTLS_ASYMMETRIC_CONTENT_LEN + help + Using dynamic TX/RX buffer. After enabling this option, mbedTLS will + allocate TX buffer when need to send data and then free it if all data + is sent, allocate RX buffer when need to receive data and then free it + when all data is used or read by upper layer. + + By default, when SSL is initialized, mbedTLS also allocate TX and + RX buffer with the default value of "MBEDTLS_SSL_OUT_CONTENT_LEN" or + "MBEDTLS_SSL_IN_CONTENT_LEN", so to save more heap, users can set + the options to be an appropriate value. + + config MBEDTLS_DYNAMIC_FREE_PEER_CERT + bool "Free SSL peer certificate after its usage" + default n + depends on MBEDTLS_DYNAMIC_BUFFER + help + Free peer certificate after its usage in handshake process. + + config MBEDTLS_DYNAMIC_FREE_CONFIG_DATA + bool "Free certificate, key and DHM data after its usage" + default n + depends on MBEDTLS_DYNAMIC_BUFFER + help + Free certificate, private key and DHM data after its usage in handshake process. + + The option will decrease heap cost when handshake, but also lead to problem: + + Becasue all certificate, private key and DHM data are freed so users should register + certificate and private key to ssl config object again. + config MBEDTLS_DEBUG bool "Enable mbedTLS debugging" default n @@ -116,51 +150,6 @@ menu "mbedTLS" default 3 if MBEDTLS_DEBUG_LEVEL_DEBUG default 4 if MBEDTLS_DEBUG_LEVEL_VERBOSE - config MBEDTLS_HARDWARE_AES - bool "Enable hardware AES acceleration" - default y - help - Enable hardware accelerated AES encryption & decryption. - - Note that if the ESP32 CPU is running at 240MHz, hardware AES does not - offer any speed boost over software AES. - - config MBEDTLS_HARDWARE_MPI - bool "Enable hardware MPI (bignum) acceleration" - default n - help - Enable hardware accelerated multiple precision integer operations. - - Hardware accelerated multiplication, modulo multiplication, - and modular exponentiation for up to 4096 bit results. - - These operations are used by RSA. - - config MBEDTLS_MPI_USE_INTERRUPT - bool "Use interrupt for MPI operations" - depends on MBEDTLS_HARDWARE_MPI - default n - help - Use an interrupt to coordinate MPI operations. - - This allows other code to run on the CPU while an MPI operation is pending. - Otherwise the CPU busy-waits. - - config MBEDTLS_HARDWARE_SHA - bool "Enable hardware SHA acceleration" - default y - help - Enable hardware accelerated SHA1, SHA256, SHA384 & SHA512 in mbedTLS. - - Due to a hardware limitation, hardware acceleration is only - guaranteed if SHA digests are calculated one at a time. If more - than one SHA digest is calculated at the same time, one will - be calculated fully in hardware and the rest will be calculated - (at least partially calculated) in software. This happens automatically. - - SHA hardware acceleration is faster than software in some situations but - slower in others. You should benchmark to find the best setting for you. - config MBEDTLS_HAVE_TIME bool "Enable mbedtls time" depends on !ESP32_TIME_SYSCALL_USE_NONE @@ -366,6 +355,7 @@ menu "mbedTLS" bool "TLS: Server Support for RFC 5077 SSL session tickets" default y depends on MBEDTLS_TLS_ENABLED + depends on MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C help Server support for RFC 5077 session tickets. See mbedTLS documentation for more details. Disabling this option will save some code size. diff --git a/components/mbedtls/component.mk b/components/mbedtls/component.mk index e6551fb60..bb78c3fd2 100644 --- a/components/mbedtls/component.mk +++ b/components/mbedtls/component.mk @@ -10,3 +10,22 @@ COMPONENT_OBJEXCLUDE := mbedtls/library/net_sockets.o COMPONENT_SUBMODULES += mbedtls +ifdef CONFIG_MBEDTLS_DYNAMIC_BUFFER + +WRAP_FUNCTIONS = mbedtls_ssl_handshake_client_step \ + mbedtls_ssl_handshake_server_step \ + mbedtls_ssl_read \ + mbedtls_ssl_write \ + mbedtls_ssl_session_reset \ + mbedtls_ssl_free \ + mbedtls_ssl_setup \ + mbedtls_ssl_send_alert_message \ + mbedtls_ssl_close_notify + +WRAP_ARGUMENT := -Wl,--wrap= + +COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME) $(addprefix $(WRAP_ARGUMENT),$(WRAP_FUNCTIONS)) + +COMPONENT_SRCDIRS += port/dynamic + +endif diff --git a/components/mbedtls/mbedtls b/components/mbedtls/mbedtls index 97959e779..9ef92c551 160000 --- a/components/mbedtls/mbedtls +++ b/components/mbedtls/mbedtls @@ -1 +1 @@ -Subproject commit 97959e77912524bd8db7cbb2e00fc9f6189f7a82 +Subproject commit 9ef92c551eb8d92677034c3ec8078a8076febf41 diff --git a/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c b/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c new file mode 100644 index 000000000..8c52d1075 --- /dev/null +++ b/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c @@ -0,0 +1,543 @@ +// Copyright 2020 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 +#include "esp_mbedtls_dynamic_impl.h" + +#define COUNTER_SIZE (8) +#define CACHE_IV_SIZE (16) +#define CACHE_BUFFER_SIZE (CACHE_IV_SIZE + COUNTER_SIZE) + +#define TX_IDLE_BUFFER_SIZE (MBEDTLS_SSL_HEADER_LEN + CACHE_BUFFER_SIZE) + +static const char *TAG = "Dynamic Impl"; + +static void esp_mbedtls_set_buf_state(unsigned char *buf, esp_mbedtls_ssl_buf_states state) +{ + struct esp_mbedtls_ssl_buf *temp = __containerof(buf, struct esp_mbedtls_ssl_buf, buf[0]); + temp->state = state; +} + +static esp_mbedtls_ssl_buf_states esp_mbedtls_get_buf_state(unsigned char *buf) +{ + struct esp_mbedtls_ssl_buf *temp = __containerof(buf, struct esp_mbedtls_ssl_buf, buf[0]); + return temp->state; +} + +void esp_mbedtls_free_buf(unsigned char *buf) +{ + struct esp_mbedtls_ssl_buf *temp = __containerof(buf, struct esp_mbedtls_ssl_buf, buf[0]); + ESP_LOGV(TAG, "free buffer @ %p", temp); + mbedtls_free(temp); +} + +static void esp_mbedtls_init_ssl_buf(struct esp_mbedtls_ssl_buf *buf, unsigned int len) +{ + if (buf) { + buf->state = ESP_MBEDTLS_SSL_BUF_CACHED; + buf->len = len; + } +} + +static void esp_mbedtls_parse_record_header(mbedtls_ssl_context *ssl) +{ + ssl->in_msgtype = ssl->in_hdr[0]; + ssl->in_msglen = (ssl->in_len[0] << 8) | ssl->in_len[1]; +} + +static int tx_buffer_len(mbedtls_ssl_context *ssl, int len) +{ + (void)ssl; + + if (!len) { + return MBEDTLS_SSL_OUT_BUFFER_LEN; + } else { + return len + MBEDTLS_SSL_HEADER_LEN + + MBEDTLS_SSL_COMPRESSION_ADD + + MBEDTLS_MAX_IV_LENGTH + + MBEDTLS_SSL_MAC_ADD + + MBEDTLS_SSL_PADDING_ADD; + } +} + +static void init_tx_buffer(mbedtls_ssl_context *ssl, unsigned char *buf) +{ + /** + * In mbedtls, ssl->out_msg = ssl->out_buf + offset; + */ + if (!buf) { + int out_msg_off = (int)ssl->out_msg - (int)ssl->out_buf; + + if (!out_msg_off) { + out_msg_off = MBEDTLS_SSL_HEADER_LEN; + } + + ssl->out_buf = NULL; + ssl->out_ctr = NULL; + ssl->out_hdr = NULL; + ssl->out_len = NULL; + ssl->out_iv = NULL; + ssl->out_msg = (unsigned char *)out_msg_off; + } else { + int out_msg_off = (int)ssl->out_msg; + + ssl->out_buf = buf; + ssl->out_ctr = ssl->out_buf; + ssl->out_hdr = ssl->out_buf + 8; + ssl->out_len = ssl->out_buf + 11; + ssl->out_iv = ssl->out_buf + MBEDTLS_SSL_HEADER_LEN; + ssl->out_msg = ssl->out_buf + out_msg_off; + + ESP_LOGV(TAG, "out msg offset is %d", out_msg_off); + } + + ssl->out_msgtype = 0; + ssl->out_msglen = 0; + ssl->out_left = 0; +} + +static void init_rx_buffer(mbedtls_ssl_context *ssl, unsigned char *buf) +{ + /** + * In mbedtls, ssl->in_msg = ssl->in_buf + offset; + */ + if (!buf) { + int in_msg_off = (int)ssl->in_msg - (int)ssl->in_buf; + + if (!in_msg_off) { + in_msg_off = MBEDTLS_SSL_HEADER_LEN; + } + + ssl->in_buf = NULL; + ssl->in_ctr = NULL; + ssl->in_hdr = NULL; + ssl->in_len = NULL; + ssl->in_iv = NULL; + ssl->in_msg = (unsigned char *)in_msg_off; + } else { + int in_msg_off = (int)ssl->in_msg; + + ssl->in_buf = buf; + ssl->in_ctr = ssl->in_buf; + ssl->in_hdr = ssl->in_buf + 8; + ssl->in_len = ssl->in_buf + 11; + ssl->in_iv = ssl->in_buf + MBEDTLS_SSL_HEADER_LEN; + ssl->in_msg = ssl->in_buf + in_msg_off; + + ESP_LOGV(TAG, "in msg offset is %d", in_msg_off); + } + + ssl->in_msgtype = 0; + ssl->in_msglen = 0; + ssl->in_left = 0; +} + +static int esp_mbedtls_alloc_tx_buf(mbedtls_ssl_context *ssl, int len) +{ + struct esp_mbedtls_ssl_buf *esp_buf; + + if (ssl->out_buf) { + esp_mbedtls_free_buf(ssl->out_buf); + ssl->out_buf = NULL; + } + + esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + len); + if (!esp_buf) { + ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + len); + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + + ESP_LOGV(TAG, "add out buffer %d bytes @ %p", len, esp_buf->buf); + + esp_mbedtls_init_ssl_buf(esp_buf, len); + /** + * Mark the out_msg offset from ssl->out_buf. + * + * In mbedtls, ssl->out_msg = ssl->out_buf + offset; + */ + ssl->out_msg = (unsigned char *)MBEDTLS_SSL_HEADER_LEN; + + init_tx_buffer(ssl, esp_buf->buf); + + return 0; +} + +int esp_mbedtls_setup_tx_buffer(mbedtls_ssl_context *ssl) +{ + CHECK_OK(esp_mbedtls_alloc_tx_buf(ssl, TX_IDLE_BUFFER_SIZE)); + + /* mark the out buffer has no data cached */ + esp_mbedtls_set_buf_state(ssl->out_buf, ESP_MBEDTLS_SSL_BUF_NO_CACHED); + + return 0; +} + +void esp_mbedtls_setup_rx_buffer(mbedtls_ssl_context *ssl) +{ + ssl->in_msg = ssl->in_buf = NULL; + init_rx_buffer(ssl, NULL); +} + +int esp_mbedtls_reset_add_tx_buffer(mbedtls_ssl_context *ssl) +{ + return esp_mbedtls_alloc_tx_buf(ssl, MBEDTLS_SSL_OUT_BUFFER_LEN); +} + +int esp_mbedtls_reset_free_tx_buffer(mbedtls_ssl_context *ssl) +{ + esp_mbedtls_free_buf(ssl->out_buf); + init_tx_buffer(ssl, NULL); + + CHECK_OK(esp_mbedtls_setup_tx_buffer(ssl)); + + return 0; +} + +int esp_mbedtls_reset_add_rx_buffer(mbedtls_ssl_context *ssl) +{ + struct esp_mbedtls_ssl_buf *esp_buf; + + if (ssl->in_buf) { + esp_mbedtls_free_buf(ssl->in_buf); + ssl->in_buf = NULL; + } + + esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + MBEDTLS_SSL_IN_BUFFER_LEN); + if (!esp_buf) { + ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + MBEDTLS_SSL_IN_BUFFER_LEN); + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + + ESP_LOGV(TAG, "add in buffer %d bytes @ %p", MBEDTLS_SSL_IN_BUFFER_LEN, esp_buf->buf); + + esp_mbedtls_init_ssl_buf(esp_buf, MBEDTLS_SSL_IN_BUFFER_LEN); + /** + * Mark the in_msg offset from ssl->in_buf. + * + * In mbedtls, ssl->in_msg = ssl->in_buf + offset; + */ + ssl->in_msg = (unsigned char *)MBEDTLS_SSL_HEADER_LEN; + + init_rx_buffer(ssl, esp_buf->buf); + + return 0; +} + +void esp_mbedtls_reset_free_rx_buffer(mbedtls_ssl_context *ssl) +{ + esp_mbedtls_free_buf(ssl->in_buf); + init_rx_buffer(ssl, NULL); +} + +int esp_mbedtls_add_tx_buffer(mbedtls_ssl_context *ssl, size_t buffer_len) +{ + int ret = 0; + int cached = 0; + struct esp_mbedtls_ssl_buf *esp_buf; + unsigned char cache_buf[CACHE_BUFFER_SIZE]; + + ESP_LOGV(TAG, "--> add out"); + + if (ssl->out_buf) { + if (esp_mbedtls_get_buf_state(ssl->out_buf) == ESP_MBEDTLS_SSL_BUF_CACHED) { + ESP_LOGV(TAG, "out buffer is not empty"); + ret = 0; + goto exit; + } else { + memcpy(cache_buf, ssl->out_buf, CACHE_BUFFER_SIZE); + esp_mbedtls_free_buf(ssl->out_buf); + init_tx_buffer(ssl, NULL); + cached = 1; + } + } + + buffer_len = tx_buffer_len(ssl, buffer_len); + + esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + buffer_len); + if (!esp_buf) { + ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + buffer_len); + ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; + goto exit; + } + + ESP_LOGV(TAG, "add out buffer %d bytes @ %p", buffer_len, esp_buf->buf); + + esp_mbedtls_init_ssl_buf(esp_buf, buffer_len); + init_tx_buffer(ssl, esp_buf->buf); + + if (cached) { + memcpy(ssl->out_ctr, cache_buf, COUNTER_SIZE); + memcpy(ssl->out_iv, cache_buf + COUNTER_SIZE, CACHE_IV_SIZE); + } + + ESP_LOGV(TAG, "ssl->out_buf=%p ssl->out_msg=%p", ssl->out_buf, ssl->out_msg); + +exit: + ESP_LOGV(TAG, "<-- add out"); + + return ret; +} + + +int esp_mbedtls_free_tx_buffer(mbedtls_ssl_context *ssl) +{ + int ret = 0; + unsigned char buf[CACHE_BUFFER_SIZE]; + struct esp_mbedtls_ssl_buf *esp_buf; + + ESP_LOGV(TAG, "--> free out"); + + if (!ssl->out_buf || (ssl->out_buf && (esp_mbedtls_get_buf_state(ssl->out_buf) == ESP_MBEDTLS_SSL_BUF_NO_CACHED))) { + ret = 0; + goto exit; + } + + memcpy(buf, ssl->out_ctr, COUNTER_SIZE); + memcpy(buf + COUNTER_SIZE, ssl->out_iv, CACHE_IV_SIZE); + + esp_mbedtls_free_buf(ssl->out_buf); + init_tx_buffer(ssl, NULL); + + esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + TX_IDLE_BUFFER_SIZE); + if (!esp_buf) { + ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + TX_IDLE_BUFFER_SIZE); + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + + esp_mbedtls_init_ssl_buf(esp_buf, TX_IDLE_BUFFER_SIZE); + memcpy(esp_buf->buf, buf, CACHE_BUFFER_SIZE); + init_tx_buffer(ssl, esp_buf->buf); + esp_mbedtls_set_buf_state(ssl->out_buf, ESP_MBEDTLS_SSL_BUF_NO_CACHED); +exit: + ESP_LOGV(TAG, "<-- free out"); + + return ret; +} + +int esp_mbedtls_add_rx_buffer(mbedtls_ssl_context *ssl) +{ + int cached = 0; + int ret = 0; + int buffer_len; + struct esp_mbedtls_ssl_buf *esp_buf; + unsigned char cache_buf[16]; + unsigned char msg_head[5]; + size_t in_msglen, in_left; + + ESP_LOGV(TAG, "--> add rx"); + + if (ssl->in_buf) { + if (esp_mbedtls_get_buf_state(ssl->in_buf) == ESP_MBEDTLS_SSL_BUF_CACHED) { + ESP_LOGV(TAG, "in buffer is not empty"); + ret = 0; + goto exit; + } else { + cached = 1; + } + } + + ssl->in_hdr = msg_head; + ssl->in_len = msg_head + 3; + + if ((ret = mbedtls_ssl_fetch_input(ssl, mbedtls_ssl_hdr_len(ssl))) != 0) { + if (ret == MBEDTLS_ERR_SSL_TIMEOUT) { + ESP_LOGD(TAG, "mbedtls_ssl_fetch_input reads data times out"); + } else if (ret == MBEDTLS_ERR_SSL_WANT_READ) { + ESP_LOGD(TAG, "mbedtls_ssl_fetch_input wants to read more data"); + } else { + ESP_LOGE(TAG, "mbedtls_ssl_fetch_input error=-0x%x", -ret); + } + + goto exit; + } + + esp_mbedtls_parse_record_header(ssl); + + in_left = ssl->in_left; + in_msglen = ssl->in_msglen; + buffer_len = tx_buffer_len(ssl, in_msglen); + + ESP_LOGV(TAG, "message length is %d RX buffer length should be %d left is %d", + (int)in_msglen, (int)buffer_len, (int)ssl->in_left); + + if (cached) { + memcpy(cache_buf, ssl->in_buf, 16); + esp_mbedtls_free_buf(ssl->in_buf); + init_rx_buffer(ssl, NULL); + } + + esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + buffer_len); + if (!esp_buf) { + ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + buffer_len); + ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; + goto exit; + } + + ESP_LOGV(TAG, "add in buffer %d bytes @ %p", buffer_len, esp_buf->buf); + + esp_mbedtls_init_ssl_buf(esp_buf, buffer_len); + init_rx_buffer(ssl, esp_buf->buf); + + if (cached) { + memcpy(ssl->in_ctr, cache_buf, 8); + memcpy(ssl->in_iv, cache_buf + 8, 8); + } + + memcpy(ssl->in_hdr, msg_head, in_left); + ssl->in_left = in_left; + ssl->in_msglen = 0; + +exit: + ESP_LOGV(TAG, "<-- add rx"); + + return ret; +} + +int esp_mbedtls_free_rx_buffer(mbedtls_ssl_context *ssl) +{ + int ret = 0; + unsigned char buf[16]; + struct esp_mbedtls_ssl_buf *esp_buf; + + ESP_LOGV(TAG, "--> free rx"); + + /** + * When have read multi messages once, can't free the input buffer directly. + */ + if (!ssl->in_buf || (ssl->in_hslen && (ssl->in_hslen < ssl->in_msglen)) || + (ssl->in_buf && (esp_mbedtls_get_buf_state(ssl->in_buf) == ESP_MBEDTLS_SSL_BUF_NO_CACHED))) { + ret = 0; + goto exit; + } + + /** + * The previous processing is just skipped, so "ssl->in_msglen = 0" + */ + if (!ssl->in_msgtype) { + goto exit; + } + + memcpy(buf, ssl->in_ctr, 8); + memcpy(buf + 8, ssl->in_iv, 8); + + esp_mbedtls_free_buf(ssl->in_buf); + init_rx_buffer(ssl, NULL); + + esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + 16); + if (!esp_buf) { + ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + 16); + ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; + goto exit; + } + + esp_mbedtls_init_ssl_buf(esp_buf, 16); + memcpy(esp_buf->buf, buf, 16); + init_rx_buffer(ssl, esp_buf->buf); + esp_mbedtls_set_buf_state(ssl->in_buf, ESP_MBEDTLS_SSL_BUF_NO_CACHED); +exit: + ESP_LOGV(TAG, "<-- free rx"); + + return ret; +} + +size_t esp_mbedtls_get_crt_size(mbedtls_x509_crt *cert, size_t *num) +{ + size_t n = 0; + size_t bytes = 0; + + while (cert) { + bytes += cert->raw.len; + n++; + + cert = cert->next; + } + + *num = n; + + return bytes; +} + +#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA +void esp_mbedtls_free_dhm(mbedtls_ssl_context *ssl) +{ + mbedtls_mpi_free((mbedtls_mpi *)&ssl->conf->dhm_P); + mbedtls_mpi_free((mbedtls_mpi *)&ssl->conf->dhm_G); +} + +void esp_mbedtls_free_keycert(mbedtls_ssl_context *ssl) +{ + mbedtls_ssl_config *conf = (mbedtls_ssl_config *)ssl->conf; + mbedtls_ssl_key_cert *keycert = conf->key_cert, *next; + + while (keycert) { + next = keycert->next; + + if (keycert) { + mbedtls_free(keycert); + } + + keycert = next; + } + + conf->key_cert = NULL; +} + +void esp_mbedtls_free_keycert_key(mbedtls_ssl_context *ssl) +{ + mbedtls_ssl_key_cert *keycert = ssl->conf->key_cert; + + while (keycert) { + if (keycert->key) { + mbedtls_pk_free(keycert->key); + keycert->key = NULL; + } + keycert = keycert->next; + } +} + +void esp_mbedtls_free_keycert_cert(mbedtls_ssl_context *ssl) +{ + mbedtls_ssl_key_cert *keycert = ssl->conf->key_cert; + + while (keycert) { + if (keycert->cert) { + mbedtls_x509_crt_free(keycert->cert); + keycert->cert = NULL; + } + keycert = keycert->next; + } +} + +void esp_mbedtls_free_cacert(mbedtls_ssl_context *ssl) +{ + if (ssl->conf->ca_chain) { + mbedtls_ssl_config *conf = (mbedtls_ssl_config *)ssl->conf; + + mbedtls_x509_crt_free(conf->ca_chain); + conf->ca_chain = NULL; + } +} + +#endif + +#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT +void esp_mbedtls_free_peer_cert(mbedtls_ssl_context *ssl) +{ + if (ssl->session_negotiate->peer_cert) { + mbedtls_x509_crt_free( ssl->session_negotiate->peer_cert ); + mbedtls_free( ssl->session_negotiate->peer_cert ); + ssl->session_negotiate->peer_cert = NULL; + } +} +#endif diff --git a/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.h b/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.h new file mode 100644 index 000000000..9e8d3a01d --- /dev/null +++ b/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.h @@ -0,0 +1,97 @@ +// Copyright 2020 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 + +#ifndef _DYNAMIC_IMPL_H_ +#define _DYNAMIC_IMPL_H_ + +#include +#include "mbedtls/ssl.h" +#include "mbedtls/ssl_internal.h" +#include "mbedtls/platform.h" +#include "esp_log.h" + +#define TRACE_CHECK(_fn, _state) \ +({ \ + ESP_LOGV(TAG, "%d " _state " to do \"%s\"", __LINE__, # _fn); \ +}) + +#define CHECK_OK(_fn) \ +({ \ + int _ret; \ + \ + TRACE_CHECK(_fn, "state"); \ + \ + if ((_ret = _fn) != 0) { \ + ESP_LOGV(TAG, "\"%s\" result is -0x%x", # _fn, -_ret); \ + TRACE_CHECK(_fn, "fail"); \ + return _ret; \ + } \ + \ + TRACE_CHECK(_fn, "end"); \ + \ +}) + +typedef enum { + ESP_MBEDTLS_SSL_BUF_CACHED, + ESP_MBEDTLS_SSL_BUF_NO_CACHED, +} esp_mbedtls_ssl_buf_states; + +struct esp_mbedtls_ssl_buf { + esp_mbedtls_ssl_buf_states state; + unsigned int len; + unsigned char buf[]; +}; + +#define SSL_BUF_HEAD_OFFSET_SIZE offsetof(struct esp_mbedtls_ssl_buf, buf) + +void esp_mbedtls_free_buf(unsigned char *buf); + +int esp_mbedtls_setup_tx_buffer(mbedtls_ssl_context *ssl); + +void esp_mbedtls_setup_rx_buffer(mbedtls_ssl_context *ssl); + +int esp_mbedtls_reset_add_tx_buffer(mbedtls_ssl_context *ssl); + +int esp_mbedtls_reset_add_rx_buffer(mbedtls_ssl_context *ssl); + +int esp_mbedtls_reset_free_tx_buffer(mbedtls_ssl_context *ssl); + +void esp_mbedtls_reset_free_rx_buffer(mbedtls_ssl_context *ssl); + +int esp_mbedtls_add_tx_buffer(mbedtls_ssl_context *ssl, size_t buffer_len); + +int esp_mbedtls_add_rx_buffer(mbedtls_ssl_context *ssl); + +int esp_mbedtls_free_tx_buffer(mbedtls_ssl_context *ssl); + +int esp_mbedtls_free_rx_buffer(mbedtls_ssl_context *ssl); + +size_t esp_mbedtls_get_crt_size(mbedtls_x509_crt *cert, size_t *num); + +#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA +void esp_mbedtls_free_dhm(mbedtls_ssl_context *ssl); + +void esp_mbedtls_free_keycert(mbedtls_ssl_context *ssl); + +void esp_mbedtls_free_keycert_cert(mbedtls_ssl_context *ssl); + +void esp_mbedtls_free_keycert_key(mbedtls_ssl_context *ssl); + +void esp_mbedtls_free_cacert(mbedtls_ssl_context *ssl); +#endif + +#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT +void esp_mbedtls_free_peer_cert(mbedtls_ssl_context *ssl); +#endif + +#endif /* _DYNAMIC_IMPL_H_ */ diff --git a/components/mbedtls/port/dynamic/esp_ssl_cli.c b/components/mbedtls/port/dynamic/esp_ssl_cli.c new file mode 100644 index 000000000..12b33f3dd --- /dev/null +++ b/components/mbedtls/port/dynamic/esp_ssl_cli.c @@ -0,0 +1,202 @@ +// Copyright 2020 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 + +#include +#include +#include "esp_mbedtls_dynamic_impl.h" + +int __real_mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl); + +int __wrap_mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl); + +static const char *TAG = "SSL client"; + +static int manage_resource(mbedtls_ssl_context *ssl, bool add) +{ + int state = add ? ssl->state : ssl->state - 1; + + if (ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL) { + return 0; + } + + if (!add) { + if (!ssl->out_left) { + CHECK_OK(esp_mbedtls_free_tx_buffer(ssl)); + } + } + + switch (state) { + case MBEDTLS_SSL_HELLO_REQUEST: + break; + case MBEDTLS_SSL_CLIENT_HELLO: + if (add) { + size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN; + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); + } + break; + + + case MBEDTLS_SSL_SERVER_HELLO: + if (add) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } else { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + } + break; + case MBEDTLS_SSL_SERVER_CERTIFICATE: + if (add) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } else { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + +#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA + esp_mbedtls_free_cacert(ssl); +#endif + } + break; + case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: + if (add) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } else { + if (!ssl->keep_current_message) { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + } +#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT + esp_mbedtls_free_peer_cert(ssl); +#endif + } + break; + case MBEDTLS_SSL_CERTIFICATE_REQUEST: + if (add) { + if (!ssl->keep_current_message) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } + } else { + if (!ssl->keep_current_message) { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + } + } + break; + case MBEDTLS_SSL_SERVER_HELLO_DONE: + if (add) { + if (!ssl->keep_current_message) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } + } else { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + } + break; + + + case MBEDTLS_SSL_CLIENT_CERTIFICATE: + if (add) { + size_t buffer_len = 3; + mbedtls_ssl_key_cert *key_cert = ssl->conf->key_cert; + + while (key_cert && key_cert->cert) { + size_t num; + + buffer_len += esp_mbedtls_get_crt_size(key_cert->cert, &num); + buffer_len += num * 3; + + key_cert = key_cert->next; + } + + buffer_len = MAX(buffer_len, MBEDTLS_SSL_OUT_BUFFER_LEN); + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); + } + break; + case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: + if (add) { + size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN; + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); + } + break; + case MBEDTLS_SSL_CERTIFICATE_VERIFY: + if (add) { + size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN; + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); + } else { +#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA + esp_mbedtls_free_dhm(ssl); + esp_mbedtls_free_keycert_key(ssl); + esp_mbedtls_free_keycert(ssl); +#endif + } + break; + case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: + if (add) { + size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN; + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); + } + break; + case MBEDTLS_SSL_CLIENT_FINISHED: + if (add) { + size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN; + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); + } + break; + + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET: + if (add) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } else { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + } + break; +#endif + + + case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: + if (add) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } else { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + } + break; + case MBEDTLS_SSL_SERVER_FINISHED: + if (add) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } else { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + } + break; + case MBEDTLS_SSL_FLUSH_BUFFERS: + break; + case MBEDTLS_SSL_HANDSHAKE_WRAPUP: + break; + default: + break; + } + + return 0; +} + +int __wrap_mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl) +{ + CHECK_OK(manage_resource(ssl, true)); + + CHECK_OK(__real_mbedtls_ssl_handshake_client_step(ssl)); + + CHECK_OK(manage_resource(ssl, false)); + + return 0; +} diff --git a/components/mbedtls/port/dynamic/esp_ssl_srv.c b/components/mbedtls/port/dynamic/esp_ssl_srv.c new file mode 100644 index 000000000..c681e070c --- /dev/null +++ b/components/mbedtls/port/dynamic/esp_ssl_srv.c @@ -0,0 +1,188 @@ +// Copyright 2020 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 + +#include +#include "esp_mbedtls_dynamic_impl.h" + +int __real_mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl); + +int __wrap_mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl); + +static const char *TAG = "SSL Server"; + +static int manage_resource(mbedtls_ssl_context *ssl, bool add) +{ + int state = add ? ssl->state : ssl->state - 1; + + if (ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL) { + return 0; + } + + if (!add) { + if (!ssl->out_left) { + CHECK_OK(esp_mbedtls_free_tx_buffer(ssl)); + } + } + + switch (state) { + case MBEDTLS_SSL_HELLO_REQUEST: + ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; + break; + case MBEDTLS_SSL_CLIENT_HELLO: + if (add) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } else { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + } + break; + + + case MBEDTLS_SSL_SERVER_HELLO: + if (add) { + size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN; + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); + } + break; + case MBEDTLS_SSL_SERVER_CERTIFICATE: + if (add) { + size_t buffer_len = 3; + mbedtls_ssl_key_cert *key_cert = ssl->conf->key_cert; + + while (key_cert && key_cert->cert) { + size_t num; + + buffer_len += esp_mbedtls_get_crt_size(key_cert->cert, &num); + buffer_len += num * 3; + + key_cert = key_cert->next; + } + + buffer_len = MAX(buffer_len, MBEDTLS_SSL_OUT_BUFFER_LEN); + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); + } else { +#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA + esp_mbedtls_free_keycert_cert(ssl); +#endif + } + break; + case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: + if (add) { + size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN; + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); + } else { +#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA + esp_mbedtls_free_dhm(ssl); + esp_mbedtls_free_keycert_key(ssl); + esp_mbedtls_free_keycert(ssl); +#endif + } + break; + case MBEDTLS_SSL_CERTIFICATE_REQUEST: + if (add) { + size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN; + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); + } + break; + case MBEDTLS_SSL_SERVER_HELLO_DONE: + if (add) { + size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN; + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); + } + break; + + + case MBEDTLS_SSL_CLIENT_CERTIFICATE: + if (add) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } else { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + +#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA + esp_mbedtls_free_cacert(ssl); +#endif + } + break; + case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: + if (add) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } else { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + } + break; + case MBEDTLS_SSL_CERTIFICATE_VERIFY: + if (add) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } else { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + } + break; + case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: + if (add) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } else { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + +#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT + esp_mbedtls_free_peer_cert(ssl); +#endif + } + break; + case MBEDTLS_SSL_CLIENT_FINISHED: + if (add) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } else { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + } + break; + + + case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: + if (add) { + size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN; + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); + } + break; + case MBEDTLS_SSL_SERVER_FINISHED: + if (add) { + size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN; + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); + } + break; + case MBEDTLS_SSL_FLUSH_BUFFERS: + break; + case MBEDTLS_SSL_HANDSHAKE_WRAPUP: + break; + default: + break; + } + + return 0; +} + +int __wrap_mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl) +{ + CHECK_OK(manage_resource(ssl, true)); + + CHECK_OK(__real_mbedtls_ssl_handshake_server_step(ssl)); + + CHECK_OK(manage_resource(ssl, false)); + + return 0; +} diff --git a/components/mbedtls/port/dynamic/esp_ssl_tls.c b/components/mbedtls/port/dynamic/esp_ssl_tls.c new file mode 100644 index 000000000..d8b4506b5 --- /dev/null +++ b/components/mbedtls/port/dynamic/esp_ssl_tls.c @@ -0,0 +1,167 @@ +// Copyright 2020 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 + +#include +#include "esp_mbedtls_dynamic_impl.h" + +int __real_mbedtls_ssl_write(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len); +int __real_mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len); +void __real_mbedtls_ssl_free(mbedtls_ssl_context *ssl); +int __real_mbedtls_ssl_session_reset(mbedtls_ssl_context *ssl); +int __real_mbedtls_ssl_setup(mbedtls_ssl_context *ssl, const mbedtls_ssl_config *conf); +int __real_mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl, unsigned char level, unsigned char message); +int __real_mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl); + +int __wrap_mbedtls_ssl_write(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len); +int __wrap_mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len); +void __wrap_mbedtls_ssl_free(mbedtls_ssl_context *ssl); +int __wrap_mbedtls_ssl_session_reset(mbedtls_ssl_context *ssl); +int __wrap_mbedtls_ssl_setup(mbedtls_ssl_context *ssl, const mbedtls_ssl_config *conf); +int __wrap_mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl, unsigned char level, unsigned char message); +int __wrap_mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl); + +static const char *TAG = "SSL TLS"; + +static int tx_done(mbedtls_ssl_context *ssl) +{ + if (!ssl->out_left) + return 1; + + return 0; +} + +static int rx_done(mbedtls_ssl_context *ssl) +{ + if (!ssl->in_msglen) { + return 1; + } + + ESP_LOGD(TAG, "RX left %d bytes", ssl->in_msglen); + + return 0; +} + +int __wrap_mbedtls_ssl_setup(mbedtls_ssl_context *ssl, const mbedtls_ssl_config *conf) +{ + CHECK_OK(__real_mbedtls_ssl_setup(ssl, conf)); + + mbedtls_free(ssl->out_buf); + ssl->out_buf = NULL; + CHECK_OK(esp_mbedtls_setup_tx_buffer(ssl)); + + mbedtls_free(ssl->in_buf); + ssl->in_buf = NULL; + esp_mbedtls_setup_rx_buffer(ssl); + + return 0; +} + +int __wrap_mbedtls_ssl_write(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len) +{ + int ret; + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, 0)); + + ret = __real_mbedtls_ssl_write(ssl, buf, len); + + if (tx_done(ssl)) { + CHECK_OK(esp_mbedtls_free_tx_buffer(ssl)); + } + + return ret; +} + +int __wrap_mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len) +{ + int ret; + + ESP_LOGD(TAG, "add mbedtls RX buffer"); + ret = esp_mbedtls_add_rx_buffer(ssl); + if (ret == MBEDTLS_ERR_SSL_CONN_EOF) { + ESP_LOGD(TAG, "fail, the connection indicated an EOF"); + return 0; + } else if (ret < 0) { + ESP_LOGD(TAG, "fail, error=-0x%x", -ret); + return ret; + } + ESP_LOGD(TAG, "end"); + + ret = __real_mbedtls_ssl_read(ssl, buf, len); + + if (rx_done(ssl)) { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + } + + return ret; +} + +void __wrap_mbedtls_ssl_free(mbedtls_ssl_context *ssl) +{ + if (ssl->out_buf) { + esp_mbedtls_free_buf(ssl->out_buf); + ssl->out_buf = NULL; + } + + if (ssl->in_buf) { + esp_mbedtls_free_buf(ssl->in_buf); + ssl->in_buf = NULL; + } + + __real_mbedtls_ssl_free(ssl); +} + +int __wrap_mbedtls_ssl_session_reset(mbedtls_ssl_context *ssl) +{ + CHECK_OK(esp_mbedtls_reset_add_tx_buffer(ssl)); + + CHECK_OK(esp_mbedtls_reset_add_rx_buffer(ssl)); + + CHECK_OK(__real_mbedtls_ssl_session_reset(ssl)); + + CHECK_OK(esp_mbedtls_reset_free_tx_buffer(ssl)); + + esp_mbedtls_reset_free_rx_buffer(ssl); + + return 0; +} + +int __wrap_mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl, unsigned char level, unsigned char message) +{ + int ret; + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, 0)); + + ret = __real_mbedtls_ssl_send_alert_message(ssl, level, message); + + if (tx_done(ssl)) { + CHECK_OK(esp_mbedtls_free_tx_buffer(ssl)); + } + + return ret; +} + +int __wrap_mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl) +{ + int ret; + + CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, 0)); + + ret = __real_mbedtls_ssl_close_notify(ssl); + + if (tx_done(ssl)) { + CHECK_OK(esp_mbedtls_free_tx_buffer(ssl)); + } + + return ret; +} + diff --git a/components/mbedtls/port/esp8266/include/sha256_alt.h b/components/mbedtls/port/esp8266/include/sha256_alt.h index 914ac89a4..fa173c1b8 100644 --- a/components/mbedtls/port/esp8266/include/sha256_alt.h +++ b/components/mbedtls/port/esp8266/include/sha256_alt.h @@ -31,7 +31,7 @@ extern "C" { #include "esp_sha.h" -typedef esp_sha_t mbedtls_sha256_context; +typedef esp_sha256_t mbedtls_sha256_context; #endif /* MBEDTLS_SHA256_ALT */ diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index bdb9bf61a..c8f682e2e 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -108,40 +108,21 @@ * within the modules that are enabled. * \{ */ - -/* The following units have ESP32 hardware support, - uncommenting each _ALT macro will use the - hardware-accelerated implementation. */ -#ifdef CONFIG_MBEDTLS_HARDWARE_AES #define MBEDTLS_AES_ALT -#else -#undef MBEDTLS_AES_ALT -#endif /* MBEDTLS_SHAxx_ALT to enable hardware SHA support with software fallback. */ -#ifdef CONFIG_MBEDTLS_HARDWARE_SHA #define MBEDTLS_SHA1_ALT #define MBEDTLS_SHA256_ALT #define MBEDTLS_SHA512_ALT -#else -#undef MBEDTLS_SHA1_ALT -#undef MBEDTLS_SHA256_ALT -#undef MBEDTLS_SHA512_ALT -#endif /* The following MPI (bignum) functions have ESP32 hardware support, Uncommenting these macros will use the hardware-accelerated implementations. */ -#ifdef CONFIG_MBEDTLS_HARDWARE_MPI -#define MBEDTLS_MPI_EXP_MOD_ALT -#define MBEDTLS_MPI_MUL_MPI_ALT -#else #undef MBEDTLS_MPI_EXP_MOD_ALT #undef MBEDTLS_MPI_MUL_MPI_ALT -#endif /** * \def MBEDTLS_ENTROPY_HARDWARE_ALT diff --git a/components/mqtt/Kconfig b/components/mqtt/Kconfig index ce14751d9..a57ed08c6 100644 --- a/components/mqtt/Kconfig +++ b/components/mqtt/Kconfig @@ -2,7 +2,7 @@ menu "MQTT" choice MQTT_LIBRARY_CHOOSE prompt "Choose MQTT library" - default MQTT_USING_IBM + default MQTT_USING_ESP help Choose the MQTT library which you want to use. @@ -11,7 +11,7 @@ choice MQTT_LIBRARY_CHOOSE config MQTT_USING_ESP bool "ESP-MQTT(Recommended)" config MQTT_USING_IBM - bool "IBM-MQTT(not recommended and will be removed at v4.0)" + bool "IBM-MQTT(not recommended and will be removed at v3.4)" endchoice menu "IBM-MQTT(paho)" diff --git a/components/mqtt/esp-mqtt/examples/emitter-client/main/app_main.c b/components/mqtt/esp-mqtt/examples/emitter-client/main/app_main.c index f8e648179..7b7197c09 100755 --- a/components/mqtt/esp-mqtt/examples/emitter-client/main/app_main.c +++ b/components/mqtt/esp-mqtt/examples/emitter-client/main/app_main.c @@ -44,7 +44,7 @@ static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/components/mqtt/esp-mqtt/include/mqtt_client.h b/components/mqtt/esp-mqtt/include/mqtt_client.h index 630ba1727..2537cf0de 100755 --- a/components/mqtt/esp-mqtt/include/mqtt_client.h +++ b/components/mqtt/esp-mqtt/include/mqtt_client.h @@ -109,8 +109,8 @@ esp_mqtt_client_handle_t esp_mqtt_client_init(const esp_mqtt_client_config_t *co esp_err_t esp_mqtt_client_set_uri(esp_mqtt_client_handle_t client, const char *uri); esp_err_t esp_mqtt_client_start(esp_mqtt_client_handle_t client); esp_err_t esp_mqtt_client_stop(esp_mqtt_client_handle_t client); -esp_err_t esp_mqtt_client_subscribe(esp_mqtt_client_handle_t client, const char *topic, int qos); -esp_err_t esp_mqtt_client_unsubscribe(esp_mqtt_client_handle_t client, const char *topic); +int esp_mqtt_client_subscribe(esp_mqtt_client_handle_t client, const char *topic, int qos); +int esp_mqtt_client_unsubscribe(esp_mqtt_client_handle_t client, const char *topic); int esp_mqtt_client_publish(esp_mqtt_client_handle_t client, const char *topic, const char *data, int len, int qos, int retain); esp_err_t esp_mqtt_client_destroy(esp_mqtt_client_handle_t client); diff --git a/components/newlib/newlib/port/include/sys/un.h b/components/newlib/newlib/port/include/sys/un.h new file mode 100644 index 000000000..6d7acdf3d --- /dev/null +++ b/components/newlib/newlib/port/include/sys/un.h @@ -0,0 +1,22 @@ +// Copyright 2020 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. + +#pragma once + +#define AF_UNIX 1 /* local to host (pipes) */ + +struct sockaddr_un { + short sun_family; /*AF_UNIX*/ + char sun_path[108]; /*path name */ +}; diff --git a/components/spi_flash/src/spi_flash.c b/components/spi_flash/src/spi_flash.c index f4c622dfb..93240e9d2 100644 --- a/components/spi_flash/src/spi_flash.c +++ b/components/spi_flash/src/spi_flash.c @@ -430,7 +430,7 @@ void user_spi_flash_dio_to_qio_pre_init(void) to_qio = true; } //ENABLE FLASH QIO 0X31H+BIT2 - } else if (((flash_id & 0xFFFFFF) == 0x1640C8) || ((flash_id & 0xFFFFFF) == 0x1840C8)) { + } else if ((flash_id & 0xFFFF) == 0x40C8) { if (flash_gd25q32c_enable_QIO_mode() == true) { to_qio = true; } diff --git a/components/tcp_transport/include/esp_transport.h b/components/tcp_transport/include/esp_transport.h index 39e694f05..4841725d0 100644 --- a/components/tcp_transport/include/esp_transport.h +++ b/components/tcp_transport/include/esp_transport.h @@ -133,7 +133,7 @@ esp_err_t esp_transport_set_default_port(esp_transport_handle_t t, int port); * @param t The transport handle * @param[in] host Hostname * @param[in] port Port - * @param[in] timeout_ms The timeout milliseconds + * @param[in] timeout_ms The timeout milliseconds (-1 indicates wait forever) * * @return * - socket for will use by this transport @@ -147,7 +147,7 @@ int esp_transport_connect(esp_transport_handle_t t, const char *host, int port, * @param t The transport handle * @param[in] host Hostname * @param[in] port Port - * @param[in] timeout_ms The timeout milliseconds + * @param[in] timeout_ms The timeout milliseconds (-1 indicates wait forever) * * @return * - socket for will use by this transport @@ -161,7 +161,7 @@ int esp_transport_connect_async(esp_transport_handle_t t, const char *host, int * @param t The transport handle * @param buffer The buffer * @param[in] len The length - * @param[in] timeout_ms The timeout milliseconds + * @param[in] timeout_ms The timeout milliseconds (-1 indicates wait forever) * * @return * - Number of bytes was read @@ -173,7 +173,7 @@ int esp_transport_read(esp_transport_handle_t t, char *buffer, int len, int time * @brief Poll the transport until readable or timeout * * @param[in] t The transport handle - * @param[in] timeout_ms The timeout milliseconds + * @param[in] timeout_ms The timeout milliseconds (-1 indicates wait forever) * * @return * - 0 Timeout @@ -188,7 +188,7 @@ int esp_transport_poll_read(esp_transport_handle_t t, int timeout_ms); * @param t The transport handle * @param buffer The buffer * @param[in] len The length - * @param[in] timeout_ms The timeout milliseconds + * @param[in] timeout_ms The timeout milliseconds (-1 indicates wait forever) * * @return * - Number of bytes was written @@ -200,7 +200,7 @@ int esp_transport_write(esp_transport_handle_t t, const char *buffer, int len, i * @brief Poll the transport until writeable or timeout * * @param[in] t The transport handle - * @param[in] timeout_ms The timeout milliseconds + * @param[in] timeout_ms The timeout milliseconds (-1 indicates wait forever) * * @return * - 0 Timeout diff --git a/components/tcp_transport/include/esp_transport_ssl.h b/components/tcp_transport/include/esp_transport_ssl.h index a83e93882..9ce0b19c3 100644 --- a/components/tcp_transport/include/esp_transport_ssl.h +++ b/components/tcp_transport/include/esp_transport_ssl.h @@ -92,6 +92,16 @@ void esp_transport_ssl_set_client_cert_data_der(esp_transport_handle_t t, const */ void esp_transport_ssl_set_client_key_data(esp_transport_handle_t t, const char *data, int len); +/** + * @brief Set SSL client key password if the key is password protected. The configured + * password is passed to the underlying TLS stack to decrypt the client key + * + * @param t ssl transport + * @param[in] password Pointer to the password + * @param[in] password_len Password length + */ +void esp_transport_ssl_set_client_key_password(esp_transport_handle_t t, const char *password, int password_len); + /** * @brief Set SSL client key data for mutual authentication (as DER format). * Note that, this function stores the pointer to data, rather than making a copy. @@ -103,6 +113,16 @@ void esp_transport_ssl_set_client_key_data(esp_transport_handle_t t, const char */ void esp_transport_ssl_set_client_key_data_der(esp_transport_handle_t t, const char *data, int len); +/** + * @brief Set the list of supported application protocols to be used with ALPN. + * Note that, this function stores the pointer to data, rather than making a copy. + * So this data must remain valid until after the connection is cleaned up + * + * @param t ssl transport + * @param[in] alpn_porot The list of ALPN protocols, the last entry must be NULL + */ +void esp_transport_ssl_set_alpn_protocol(esp_transport_handle_t t, const char **alpn_protos); + /** * @brief Skip validation of certificate's common name field * diff --git a/components/tcp_transport/include/esp_transport_ws.h b/components/tcp_transport/include/esp_transport_ws.h index 0876480a4..5e5405791 100644 --- a/components/tcp_transport/include/esp_transport_ws.h +++ b/components/tcp_transport/include/esp_transport_ws.h @@ -14,6 +14,7 @@ extern "C" { #endif typedef enum ws_transport_opcodes { + WS_TRANSPORT_OPCODES_CONT = 0x00, WS_TRANSPORT_OPCODES_TEXT = 0x01, WS_TRANSPORT_OPCODES_BINARY = 0x02, WS_TRANSPORT_OPCODES_CLOSE = 0x08, @@ -50,6 +51,30 @@ void esp_transport_ws_set_path(esp_transport_handle_t t, const char *path); */ esp_err_t esp_transport_ws_set_subprotocol(esp_transport_handle_t t, const char *sub_protocol); +/** + * @brief Set websocket user-agent header + * + * @param t websocket transport handle + * @param sub_protocol user-agent string + * + * @return + * - ESP_OK on success + * - One of the error codes + */ +esp_err_t esp_transport_ws_set_user_agent(esp_transport_handle_t t, const char *user_agent); + +/** + * @brief Set websocket additional headers + * + * @param t websocket transport handle + * @param sub_protocol additional header strings each terminated with \r\n + * + * @return + * - ESP_OK on success + * - One of the error codes + */ +esp_err_t esp_transport_ws_set_headers(esp_transport_handle_t t, const char *headers); + /** * @brief Sends websocket raw message with custom opcode and payload * @@ -63,7 +88,7 @@ esp_err_t esp_transport_ws_set_subprotocol(esp_transport_handle_t t, const char * @param[in] opcode ws operation code * @param[in] buffer The buffer * @param[in] len The length - * @param[in] timeout_ms The timeout milliseconds + * @param[in] timeout_ms The timeout milliseconds (-1 indicates block forever) * * @return * - Number of bytes was written @@ -81,6 +106,16 @@ int esp_transport_ws_send_raw(esp_transport_handle_t t, ws_transport_opcodes_t o */ ws_transport_opcodes_t esp_transport_ws_get_read_opcode(esp_transport_handle_t t); +/** + * @brief Returns payload length of the last received data + * + * @param t websocket transport handle + * + * @return + * - Number of bytes in the payload + */ +int esp_transport_ws_get_read_payload_len(esp_transport_handle_t t); + #ifdef __cplusplus } diff --git a/components/tcp_transport/include/esp_transport_utils.h b/components/tcp_transport/private_include/esp_transport_utils.h similarity index 67% rename from components/tcp_transport/include/esp_transport_utils.h rename to components/tcp_transport/private_include/esp_transport_utils.h index 6a9d1d02c..dbc91b119 100644 --- a/components/tcp_transport/include/esp_transport_utils.h +++ b/components/tcp_transport/private_include/esp_transport_utils.h @@ -30,12 +30,17 @@ extern "C" { } /** - * @brief Convert milliseconds to timeval struct + * @brief Convert milliseconds to timeval struct for valid timeouts, otherwise + * (if "wait forever" requested by timeout_ms=-1) timeval structure is not updated and NULL returned * - * @param[in] timeout_ms The timeout milliseconds - * @param[out] tv Timeval struct + * @param[in] timeout_ms The timeout value in milliseconds or -1 to waiting forever + * @param[out] tv Pointer to timeval struct + * + * @return + * - NULL if timeout_ms=-1 (wait forever) + * - pointer to the updated timeval structure (provided as "tv" argument) with recalculated timeout value */ -void esp_transport_utils_ms_to_timeval(int timeout_ms, struct timeval *tv); +struct timeval* esp_transport_utils_ms_to_timeval(int timeout_ms, struct timeval *tv); #ifdef __cplusplus diff --git a/components/tcp_transport/test/CMakeLists.txt b/components/tcp_transport/test/CMakeLists.txt index 88504a27f..89846a753 100644 --- a/components/tcp_transport/test/CMakeLists.txt +++ b/components/tcp_transport/test/CMakeLists.txt @@ -1,5 +1,3 @@ -set(COMPONENT_SRCDIRS ".") -set(COMPONENT_PRIV_INCLUDEDIRS "../private_include" ".") -set(COMPONENT_PRIV_REQUIRES unity test_utils tcp_transport) - -register_component() \ No newline at end of file +idf_component_register(SRC_DIRS "." + PRIV_INCLUDE_DIRS "../private_include" "." + PRIV_REQUIRES unity test_utils tcp_transport) \ No newline at end of file diff --git a/components/tcp_transport/transport_ssl.c b/components/tcp_transport/transport_ssl.c index b92c21157..4bca105d4 100644 --- a/components/tcp_transport/transport_ssl.c +++ b/components/tcp_transport/transport_ssl.c @@ -71,7 +71,7 @@ static int ssl_connect(esp_transport_handle_t t, const char *host, int port, int ssl->cfg.timeout_ms = timeout_ms; ssl->ssl_initialized = true; ssl->tls = esp_tls_init(); - if (esp_tls_conn_new_sync(host, strlen(host), port, &ssl->cfg, ssl->tls) < 0) { + if (esp_tls_conn_new_sync(host, strlen(host), port, &ssl->cfg, ssl->tls) <= 0) { ESP_LOGE(TAG, "Failed to open a new connection"); esp_transport_set_errors(t, ssl->tls->error_handle); esp_tls_conn_delete(ssl->tls); @@ -86,16 +86,15 @@ static int ssl_poll_read(esp_transport_handle_t t, int timeout_ms) { transport_ssl_t *ssl = esp_transport_get_context_data(t); int ret = -1; + struct timeval timeout; fd_set readset; fd_set errset; FD_ZERO(&readset); FD_ZERO(&errset); FD_SET(ssl->tls->sockfd, &readset); FD_SET(ssl->tls->sockfd, &errset); - struct timeval timeout; - esp_transport_utils_ms_to_timeval(timeout_ms, &timeout); - ret = select(ssl->tls->sockfd + 1, &readset, NULL, &errset, &timeout); + ret = select(ssl->tls->sockfd + 1, &readset, NULL, &errset, esp_transport_utils_ms_to_timeval(timeout_ms, &timeout)); if (ret > 0 && FD_ISSET(ssl->tls->sockfd, &errset)) { int sock_errno = 0; uint32_t optlen = sizeof(sock_errno); @@ -110,15 +109,14 @@ static int ssl_poll_write(esp_transport_handle_t t, int timeout_ms) { transport_ssl_t *ssl = esp_transport_get_context_data(t); int ret = -1; + struct timeval timeout; fd_set writeset; fd_set errset; FD_ZERO(&writeset); FD_ZERO(&errset); FD_SET(ssl->tls->sockfd, &writeset); FD_SET(ssl->tls->sockfd, &errset); - struct timeval timeout; - esp_transport_utils_ms_to_timeval(timeout_ms, &timeout); - ret = select(ssl->tls->sockfd + 1, NULL, &writeset, &errset, &timeout); + ret = select(ssl->tls->sockfd + 1, NULL, &writeset, &errset, esp_transport_utils_ms_to_timeval(timeout_ms, &timeout)); if (ret > 0 && FD_ISSET(ssl->tls->sockfd, &errset)) { int sock_errno = 0; uint32_t optlen = sizeof(sock_errno); @@ -247,6 +245,15 @@ void esp_transport_ssl_set_client_key_data(esp_transport_handle_t t, const char } } +void esp_transport_ssl_set_client_key_password(esp_transport_handle_t t, const char *password, int password_len) +{ + transport_ssl_t *ssl = esp_transport_get_context_data(t); + if (t && ssl) { + ssl->cfg.clientkey_password = (void *)password; + ssl->cfg.clientkey_password_len = password_len; + } +} + void esp_transport_ssl_set_client_key_data_der(esp_transport_handle_t t, const char *data, int len) { transport_ssl_t *ssl = esp_transport_get_context_data(t); @@ -256,6 +263,14 @@ void esp_transport_ssl_set_client_key_data_der(esp_transport_handle_t t, const c } } +void esp_transport_ssl_set_alpn_protocol(esp_transport_handle_t t, const char **alpn_protos) +{ + transport_ssl_t *ssl = esp_transport_get_context_data(t); + if (t && ssl) { + ssl->cfg.alpn_protos = alpn_protos; + } +} + void esp_transport_ssl_skip_common_name_check(esp_transport_handle_t t) { transport_ssl_t *ssl = esp_transport_get_context_data(t); diff --git a/components/tcp_transport/transport_tcp.c b/components/tcp_transport/transport_tcp.c index 3fba399a0..5bfb99ddf 100644 --- a/components/tcp_transport/transport_tcp.c +++ b/components/tcp_transport/transport_tcp.c @@ -52,7 +52,7 @@ static int resolve_dns(const char *host, struct sockaddr_in *ip) { static int tcp_connect(esp_transport_handle_t t, const char *host, int port, int timeout_ms) { struct sockaddr_in remote_ip; - struct timeval tv; + struct timeval tv = { 0 }; transport_tcp_t *tcp = esp_transport_get_context_data(t); bzero(&remote_ip, sizeof(struct sockaddr_in)); @@ -74,7 +74,7 @@ static int tcp_connect(esp_transport_handle_t t, const char *host, int port, int remote_ip.sin_family = AF_INET; remote_ip.sin_port = htons(port); - esp_transport_utils_ms_to_timeval(timeout_ms, &tv); + esp_transport_utils_ms_to_timeval(timeout_ms, &tv); // if timeout=-1, tv is unchanged, 0, i.e. waits forever setsockopt(tcp->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); setsockopt(tcp->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); @@ -117,15 +117,15 @@ static int tcp_poll_read(esp_transport_handle_t t, int timeout_ms) { transport_tcp_t *tcp = esp_transport_get_context_data(t); int ret = -1; + struct timeval timeout; fd_set readset; fd_set errset; FD_ZERO(&readset); FD_ZERO(&errset); FD_SET(tcp->sock, &readset); FD_SET(tcp->sock, &errset); - struct timeval timeout; - esp_transport_utils_ms_to_timeval(timeout_ms, &timeout); - ret = select(tcp->sock + 1, &readset, NULL, &errset, &timeout); + + ret = select(tcp->sock + 1, &readset, NULL, &errset, esp_transport_utils_ms_to_timeval(timeout_ms, &timeout)); if (ret > 0 && FD_ISSET(tcp->sock, &errset)) { int sock_errno = 0; uint32_t optlen = sizeof(sock_errno); @@ -140,15 +140,15 @@ static int tcp_poll_write(esp_transport_handle_t t, int timeout_ms) { transport_tcp_t *tcp = esp_transport_get_context_data(t); int ret = -1; + struct timeval timeout; fd_set writeset; fd_set errset; FD_ZERO(&writeset); FD_ZERO(&errset); FD_SET(tcp->sock, &writeset); FD_SET(tcp->sock, &errset); - struct timeval timeout; - esp_transport_utils_ms_to_timeval(timeout_ms, &timeout); - ret = select(tcp->sock + 1, NULL, &writeset, &errset, &timeout); + + ret = select(tcp->sock + 1, NULL, &writeset, &errset, esp_transport_utils_ms_to_timeval(timeout_ms, &timeout)); if (ret > 0 && FD_ISSET(tcp->sock, &errset)) { int sock_errno = 0; uint32_t optlen = sizeof(sock_errno); diff --git a/components/tcp_transport/transport_utils.c b/components/tcp_transport/transport_utils.c index 9ef56dc24..5e0a02162 100644 --- a/components/tcp_transport/transport_utils.c +++ b/components/tcp_transport/transport_utils.c @@ -6,8 +6,12 @@ #include "esp_transport_utils.h" -void esp_transport_utils_ms_to_timeval(int timeout_ms, struct timeval *tv) +struct timeval* esp_transport_utils_ms_to_timeval(int timeout_ms, struct timeval *tv) { + if (timeout_ms == -1) { + return NULL; + } tv->tv_sec = timeout_ms / 1000; tv->tv_usec = (timeout_ms - (tv->tv_sec * 1000)) * 1000; + return tv; } \ No newline at end of file diff --git a/components/tcp_transport/transport_ws.c b/components/tcp_transport/transport_ws.c index 637d4d617..3cff41987 100644 --- a/components/tcp_transport/transport_ws.c +++ b/components/tcp_transport/transport_ws.c @@ -2,7 +2,6 @@ #include #include #include - #include "esp_log.h" #include "esp_transport.h" #include "esp_transport_tcp.h" @@ -15,11 +14,13 @@ static const char *TAG = "TRANSPORT_WS"; #define DEFAULT_WS_BUFFER (1024) #define WS_FIN 0x80 +#define WS_OPCODE_CONT 0x00 #define WS_OPCODE_TEXT 0x01 #define WS_OPCODE_BINARY 0x02 #define WS_OPCODE_CLOSE 0x08 #define WS_OPCODE_PING 0x09 #define WS_OPCODE_PONG 0x0a + // Second byte #define WS_MASK 0x80 #define WS_SIZE16 126 @@ -27,11 +28,21 @@ static const char *TAG = "TRANSPORT_WS"; #define MAX_WEBSOCKET_HEADER_SIZE 16 #define WS_RESPONSE_OK 101 + +typedef struct { + uint8_t opcode; + char mask_key[4]; /*!< Mask key for this payload */ + int payload_len; /*!< Total length of the payload */ + int bytes_remaining; /*!< Bytes left to read of the payload */ +} ws_transport_frame_state_t; + typedef struct { char *path; char *buffer; char *sub_protocol; - uint8_t read_opcode; + char *user_agent; + char *headers; + ws_transport_frame_state_t frame_state; esp_transport_handle_t parent; } transport_ws_t; @@ -43,6 +54,11 @@ static inline uint8_t ws_get_bin_opcode(ws_transport_opcodes_t opcode) static esp_transport_handle_t ws_get_payload_transport_handle(esp_transport_handle_t t) { transport_ws_t *ws = esp_transport_get_context_data(t); + + /* Reading parts of a frame directly will disrupt the WS internal frame state, + reset bytes_remaining to prepare for reading a new frame */ + ws->frame_state.bytes_remaining = 0; + return ws->parent; } @@ -96,24 +112,27 @@ static int ws_connect(esp_transport_handle_t t, const char *host, int port, int // Size of base64 coded string is equal '((input_size * 4) / 3) + (input_size / 96) + 6' including Z-term unsigned char client_key[28] = {0}; + const char *user_agent_ptr = (ws->user_agent)?(ws->user_agent):"ESP32 Websocket Client"; + size_t outlen = 0; mbedtls_base64_encode(client_key, sizeof(client_key), &outlen, random_key, sizeof(random_key)); int len = snprintf(ws->buffer, DEFAULT_WS_BUFFER, "GET %s HTTP/1.1\r\n" "Connection: Upgrade\r\n" "Host: %s:%d\r\n" + "User-Agent: %s\r\n" "Upgrade: websocket\r\n" "Sec-WebSocket-Version: 13\r\n" - "Sec-WebSocket-Key: %s\r\n" - "User-Agent: ESP32 Websocket Client\r\n", + "Sec-WebSocket-Key: %s\r\n", ws->path, - host, port, + host, port, user_agent_ptr, client_key); if (len <= 0 || len >= DEFAULT_WS_BUFFER) { ESP_LOGE(TAG, "Error in request generation, %d", len); return -1; } if (ws->sub_protocol) { + ESP_LOGD(TAG, "sub_protocol: %s", ws->sub_protocol); int r = snprintf(ws->buffer + len, DEFAULT_WS_BUFFER - len, "Sec-WebSocket-Protocol: %s\r\n", ws->sub_protocol); len += r; if (r <= 0 || len >= DEFAULT_WS_BUFFER) { @@ -122,6 +141,16 @@ static int ws_connect(esp_transport_handle_t t, const char *host, int port, int return -1; } } + if (ws->headers) { + ESP_LOGD(TAG, "headers: %s", ws->headers); + int r = snprintf(ws->buffer + len, DEFAULT_WS_BUFFER - len, "%s", ws->headers); + len += r; + if (r <= 0 || len >= DEFAULT_WS_BUFFER) { + ESP_LOGE(TAG, "Error in request generation" + "(strncpy of headers returned %d, desired request len: %d, buffer size: %d", r, len, DEFAULT_WS_BUFFER); + return -1; + } + } int r = snprintf(ws->buffer + len, DEFAULT_WS_BUFFER - len, "\r\n"); len += r; if (r <= 0 || len >= DEFAULT_WS_BUFFER) { @@ -233,7 +262,7 @@ static int _ws_write(esp_transport_handle_t t, int opcode, int mask_flag, const for (i = 0; i < len; ++i) { buffer[i] = (buffer[i] ^ mask[i % 4]); } - } + } return ret; } @@ -260,12 +289,46 @@ static int ws_write(esp_transport_handle_t t, const char *b, int len, int timeou return _ws_write(t, WS_OPCODE_BINARY | WS_FIN, WS_MASK, b, len, timeout_ms); } -static int ws_read(esp_transport_handle_t t, char *buffer, int len, int timeout_ms) + +static int ws_read_payload(esp_transport_handle_t t, char *buffer, int len, int timeout_ms) +{ + transport_ws_t *ws = esp_transport_get_context_data(t); + + int bytes_to_read; + int rlen = 0; + + if (ws->frame_state.bytes_remaining > len) { + ESP_LOGD(TAG, "Actual data to receive (%d) are longer than ws buffer (%d)", ws->frame_state.bytes_remaining, len); + bytes_to_read = len; + + } else { + bytes_to_read = ws->frame_state.bytes_remaining; + } + + // Receive and process payload + if (bytes_to_read != 0 && (rlen = esp_transport_read(ws->parent, buffer, bytes_to_read, timeout_ms)) <= 0) { + ESP_LOGE(TAG, "Error read data"); + return rlen; + } + ws->frame_state.bytes_remaining -= rlen; + + if (ws->frame_state.mask_key) { + for (int i = 0; i < bytes_to_read; i++) { + buffer[i] = (buffer[i] ^ ws->frame_state.mask_key[i % 4]); + } + } + return rlen; +} + + +/* Read and parse the WS header, determine length of payload */ +static int ws_read_header(esp_transport_handle_t t, char *buffer, int len, int timeout_ms) { transport_ws_t *ws = esp_transport_get_context_data(t); int payload_len; + char ws_header[MAX_WEBSOCKET_HEADER_SIZE]; - char *data_ptr = ws_header, mask, *mask_key = NULL; + char *data_ptr = ws_header, mask; int rlen; int poll_read; if ((poll_read = esp_transport_poll_read(ws->parent, timeout_ms)) <= 0) { @@ -274,16 +337,17 @@ static int ws_read(esp_transport_handle_t t, char *buffer, int len, int timeout_ // Receive and process header first (based on header size) int header = 2; + int mask_len = 4; if ((rlen = esp_transport_read(ws->parent, data_ptr, header, timeout_ms)) <= 0) { ESP_LOGE(TAG, "Error read data"); return rlen; } - ws->read_opcode = (*data_ptr & 0x0F); + ws->frame_state.opcode = (*data_ptr & 0x0F); data_ptr ++; mask = ((*data_ptr >> 7) & 0x01); payload_len = (*data_ptr & 0x7F); data_ptr++; - ESP_LOGD(TAG, "Opcode: %d, mask: %d, len: %d\r\n", ws->read_opcode, mask, payload_len); + ESP_LOGD(TAG, "Opcode: %d, mask: %d, len: %d\r\n", ws->frame_state.opcode, mask, payload_len); if (payload_len == 126) { // headerLen += 2; if ((rlen = esp_transport_read(ws->parent, data_ptr, header, timeout_ms)) <= 0) { @@ -307,27 +371,48 @@ static int ws_read(esp_transport_handle_t t, char *buffer, int len, int timeout_ } } - if (payload_len > len) { - ESP_LOGD(TAG, "Actual data to receive (%d) are longer than ws buffer (%d)", payload_len, len); - payload_len = len; + if (mask) { + // Read and store mask + if (payload_len != 0 && (rlen = esp_transport_read(ws->parent, buffer, mask_len, timeout_ms)) <= 0) { + ESP_LOGE(TAG, "Error read data"); + return rlen; + } + memcpy(ws->frame_state.mask_key, buffer, mask_len); + } else { + memset(ws->frame_state.mask_key, 0, mask_len); } - // Then receive and process payload - if (payload_len != 0 && (rlen = esp_transport_read(ws->parent, buffer, payload_len, timeout_ms)) <= 0) { - ESP_LOGE(TAG, "Error read data"); - return rlen; - } + ws->frame_state.payload_len = payload_len; + ws->frame_state.bytes_remaining = payload_len; - if (mask) { - mask_key = buffer; - data_ptr = buffer + 4; - for (int i = 0; i < payload_len; i++) { - buffer[i] = (data_ptr[i] ^ mask_key[i % 4]); + return payload_len; +} + +static int ws_read(esp_transport_handle_t t, char *buffer, int len, int timeout_ms) +{ + int rlen = 0; + transport_ws_t *ws = esp_transport_get_context_data(t); + + // If message exceeds buffer len then subsequent reads will skip reading header and read whatever is left of the payload + if (ws->frame_state.bytes_remaining <= 0) { + if ( (rlen = ws_read_header(t, buffer, len, timeout_ms)) <= 0) { + // If something when wrong then we prepare for reading a new header + ws->frame_state.bytes_remaining = 0; + return rlen; } } - return payload_len; + if (ws->frame_state.payload_len) { + if ( (rlen = ws_read_payload(t, buffer, len, timeout_ms)) <= 0) { + ESP_LOGE(TAG, "Error reading payload data"); + ws->frame_state.bytes_remaining = 0; + return rlen; + } + } + + return rlen; } + static int ws_poll_read(esp_transport_handle_t t, int timeout_ms) { transport_ws_t *ws = esp_transport_get_context_data(t); @@ -352,6 +437,8 @@ static esp_err_t ws_destroy(esp_transport_handle_t t) free(ws->buffer); free(ws->path); free(ws->sub_protocol); + free(ws->user_agent); + free(ws->headers); free(ws); return 0; } @@ -409,8 +496,56 @@ esp_err_t esp_transport_ws_set_subprotocol(esp_transport_handle_t t, const char return ESP_OK; } +esp_err_t esp_transport_ws_set_user_agent(esp_transport_handle_t t, const char *user_agent) +{ + if (t == NULL) { + return ESP_ERR_INVALID_ARG; + } + transport_ws_t *ws = esp_transport_get_context_data(t); + if (ws->user_agent) { + free(ws->user_agent); + } + if (user_agent == NULL) { + ws->user_agent = NULL; + return ESP_OK; + } + ws->user_agent = strdup(user_agent); + if (ws->user_agent == NULL) { + return ESP_ERR_NO_MEM; + } + return ESP_OK; +} + +esp_err_t esp_transport_ws_set_headers(esp_transport_handle_t t, const char *headers) +{ + if (t == NULL) { + return ESP_ERR_INVALID_ARG; + } + transport_ws_t *ws = esp_transport_get_context_data(t); + if (ws->headers) { + free(ws->headers); + } + if (headers == NULL) { + ws->headers = NULL; + return ESP_OK; + } + ws->headers = strdup(headers); + if (ws->headers == NULL) { + return ESP_ERR_NO_MEM; + } + return ESP_OK; +} + ws_transport_opcodes_t esp_transport_ws_get_read_opcode(esp_transport_handle_t t) { transport_ws_t *ws = esp_transport_get_context_data(t); - return ws->read_opcode; + return ws->frame_state.opcode; } + +int esp_transport_ws_get_read_payload_len(esp_transport_handle_t t) +{ + transport_ws_t *ws = esp_transport_get_context_data(t); + return ws->frame_state.payload_len; +} + + diff --git a/components/tcpip_adapter/esp_netif.c b/components/tcpip_adapter/esp_netif.c new file mode 100644 index 000000000..72de962f4 --- /dev/null +++ b/components/tcpip_adapter/esp_netif.c @@ -0,0 +1,27 @@ +// Copyright 2020-2021 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 "esp_netif.h" + +esp_err_t esp_netif_init(void) +{ + tcpip_adapter_init(); + + return ESP_OK; +} + +esp_err_t esp_netif_deinit(void) +{ + return ESP_OK; +} diff --git a/components/tcpip_adapter/include/esp_netif.h b/components/tcpip_adapter/include/esp_netif.h new file mode 100644 index 000000000..7c71f18a6 --- /dev/null +++ b/components/tcpip_adapter/include/esp_netif.h @@ -0,0 +1,58 @@ +// Copyright 2020 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. + +#pragma once + +#include +#include "sdkconfig.h" +#include "esp_wifi_types.h" +#include "tcpip_adapter.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ESP_NETIF_INIT_API ESP-NETIF Initialization API + * @brief Add these APIs to make code compatible with esp-idf's newer branch + * + */ + +/** @addtogroup ESP_NETIF_INIT_API + * @{ + */ + +/** + * @brief Wrapper API to call "tcpip_adapter_init()" really + * + * @return + * - ESP_OK on success + + * @note This function should be called exactly once from application code, when the application starts up. + */ +esp_err_t esp_netif_init(void); + +/** + * @brief Empty function + * + * Note: Deinitialization is not supported yet + * + * @return + * - ESP_OK on success + */ +esp_err_t esp_netif_deinit(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/tcpip_adapter/tcpip_adapter_lwip.c b/components/tcpip_adapter/tcpip_adapter_lwip.c index 77d28d99a..ff2e6086c 100644 --- a/components/tcpip_adapter/tcpip_adapter_lwip.c +++ b/components/tcpip_adapter/tcpip_adapter_lwip.c @@ -93,6 +93,7 @@ static void tcpip_adapter_dhcps_cb(u8_t client_ip[4]) client_ip[0],client_ip[1],client_ip[2],client_ip[3]); system_event_t evt; evt.event_id = SYSTEM_EVENT_AP_STAIPASSIGNED; + memcpy(&evt.event_info.ap_staipassigned.ip, client_ip, sizeof(ip4_addr_t)); esp_event_send(&evt); } diff --git a/components/util/Kconfig b/components/util/Kconfig index cb741d4e5..676a956a5 100644 --- a/components/util/Kconfig +++ b/components/util/Kconfig @@ -11,7 +11,7 @@ config util_assert config ESP_SHA bool "Enable Espressif SHA" - default y + default n help Enable Espressif SHA1, SHA256, SHA384 & SHA512 for other components to save code size for ESP8285(ESP8266 + 1MB flash) users. diff --git a/components/util/include/esp_sha.h b/components/util/include/esp_sha.h index e7d819e9c..238d1be12 100644 --- a/components/util/include/esp_sha.h +++ b/components/util/include/esp_sha.h @@ -21,63 +21,31 @@ extern "C" { #endif -typedef int (*sha_cal_t)(void *ctx, const void *src); +typedef struct { + uint32_t state[5]; + uint32_t total[2]; + uint8_t buffer[64]; +} esp_sha1_t; -typedef enum { - SHA1 = 0, - SHA224 = 1, - SHA256 = 2, - SHA384 = 3, - SHA512 = 4, +typedef struct { + uint32_t total[2]; + uint32_t state[8]; + uint8_t buffer[64]; - SHA_INVALID = -1, -} esp_sha_type_t; + int is224; +} esp_sha256_t; typedef struct { - esp_sha_type_t type; /*!< The sha type */ - uint8_t buffer[64]; /*!< The data block being processed. */ - uint32_t total[2]; /*!< The number of Bytes processed. */ - uint32_t state[8]; /*!< The intermediate digest state. */ - sha_cal_t sha_cal; /*!< The sha calculation. */ -} esp_sha_t; + uint64_t total[2]; + uint64_t state[8]; + uint8_t buffer[128]; -typedef struct { - esp_sha_type_t type; /*!< The sha type */ - uint8_t buffer[128]; /*!< The data block being processed. */ - uint64_t total[2]; /*!< The number of Bytes processed. */ - uint64_t state[8]; /*!< The intermediate digest state. */ - sha_cal_t sha_cal; /*!< The sha calculation. */ + int is384; } esp_sha512_t; -typedef esp_sha_t esp_sha1_t; -typedef esp_sha_t esp_sha224_t; -typedef esp_sha_t esp_sha256_t; -typedef esp_sha512_t esp_sha384_t; - -/** - * @brief initialize the SHA(1/224/256) contex - * - * @param ctx SHA contex pointer - * @param type SHA type - * @param state_ctx SHA calculation factor - * @param size calculation factor size by "uint32_t" - * @param sha_cal calculation function for real SHA - * - * @return 0 if success or fail - */ -int __esp_sha_init(esp_sha_t *ctx, esp_sha_type_t type, const uint32_t *state_ctx, size_t size, sha_cal_t sha_cal); +typedef esp_sha256_t esp_sha224_t; -/** - * @brief initialize the SHA(384/512) contex - * - * @param ctx SHA contex pointer - * @param type SHA type - * @param state_ctx SHA calculation factor - * @param size calculation factor size by "uint64_t" - * - * @return 0 if success or fail - */ -int __esp_sha512_init(esp_sha512_t *ctx, esp_sha_type_t type, const uint64_t *state_ctx, size_t size); +typedef esp_sha512_t esp_sha384_t; /** * @brief initialize the SHA1 contex @@ -86,13 +54,7 @@ int __esp_sha512_init(esp_sha512_t *ctx, esp_sha_type_t type, const uint64_t *st * * @return 0 if success or fail */ -static inline int esp_sha1_init(esp_sha1_t *ctx) -{ - extern const uint32_t __g_esp_sha1_state_ctx[]; - extern int __esp_sha1_process(void *ctx, const void *data); - - return __esp_sha_init(ctx, SHA1, __g_esp_sha1_state_ctx, 5, __esp_sha1_process); -} +int esp_sha1_init(esp_sha1_t *ctx); /** * @brief initialize the SHA224 contex @@ -101,13 +63,7 @@ static inline int esp_sha1_init(esp_sha1_t *ctx) * * @return 0 if success or fail */ -static inline int esp_sha224_init(esp_sha224_t *ctx) -{ - extern const uint32_t __g_esp_sha224_state_ctx[]; - extern int __esp_sha256_process(void *ctx, const void *data); - - return __esp_sha_init(ctx, SHA224, __g_esp_sha224_state_ctx, 8, __esp_sha256_process); -} +int esp_sha224_init(esp_sha224_t *ctx); /** * @brief initialize the SHA256 contex @@ -116,13 +72,7 @@ static inline int esp_sha224_init(esp_sha224_t *ctx) * * @return 0 if success or fail */ -static inline int esp_sha256_init(esp_sha256_t *ctx) -{ - extern const uint32_t __g_esp_sha256_state_ctx[]; - extern int __esp_sha256_process(void *ctx, const void *data); - - return __esp_sha_init(ctx, SHA256, __g_esp_sha256_state_ctx, 8, __esp_sha256_process); -} +int esp_sha256_init(esp_sha256_t *ctx); /** * @brief initialize the SHA384 contex @@ -131,12 +81,7 @@ static inline int esp_sha256_init(esp_sha256_t *ctx) * * @return 0 if success or fail */ -static inline int esp_sha384_init(esp_sha384_t *ctx) -{ - extern const uint64_t __g_esp_sha384_state_ctx[]; - - return __esp_sha512_init(ctx, SHA384, __g_esp_sha384_state_ctx, 8); -} +int esp_sha384_init(esp_sha384_t *ctx); /** * @brief initialize the SHA512 contex @@ -145,23 +90,7 @@ static inline int esp_sha384_init(esp_sha384_t *ctx) * * @return 0 if success or fail */ -static inline int esp_sha512_init(esp_sha512_t *ctx) -{ - extern const uint64_t __g_esp_sha512_state_ctx[]; - - return __esp_sha512_init(ctx, SHA512, __g_esp_sha512_state_ctx, 8); -} - -/** - * @brief calculate input data for SHA - * - * @param ctx SHA contex pointer - * @param src input data buffer pointer - * @param size input data bytes - * - * @return 0 if success or fail - */ -int __esp_sha_update(esp_sha_t *ctx, const void *src, size_t size); +int esp_sha512_init(esp_sha512_t *ctx); /** * @brief calculate input data for SHA1 @@ -172,10 +101,7 @@ int __esp_sha_update(esp_sha_t *ctx, const void *src, size_t size); * * @return 0 if success or fail */ -static inline int esp_sha1_update(esp_sha1_t *ctx, const void *src, size_t size) -{ - return __esp_sha_update(ctx, src, size); -} +int esp_sha1_update(esp_sha1_t *ctx, const void *src, size_t size); /** * @brief calculate input data for SHA224 @@ -186,10 +112,7 @@ static inline int esp_sha1_update(esp_sha1_t *ctx, const void *src, size_t size) * * @return 0 if success or fail */ -static inline int esp_sha224_update(esp_sha224_t *ctx, const void *src, size_t size) -{ - return __esp_sha_update(ctx, src, size); -} +int esp_sha224_update(esp_sha224_t *ctx, const void *src, size_t size); /** * @brief calculate input data for SHA256 @@ -200,10 +123,7 @@ static inline int esp_sha224_update(esp_sha224_t *ctx, const void *src, size_t s * * @return 0 if success or fail */ -static inline int esp_sha256_update(esp_sha256_t *ctx, const void *src, size_t size) -{ - return __esp_sha_update(ctx, src, size); -} +int esp_sha256_update(esp_sha256_t *ctx, const void *src, size_t size); /** * @brief calculate input data for SHA384 @@ -214,10 +134,7 @@ static inline int esp_sha256_update(esp_sha256_t *ctx, const void *src, size_t s * * @return 0 if success or fail */ -static inline int esp_sha384_update(esp_sha384_t *ctx, const void *src, size_t size) -{ - return __esp_sha_update((esp_sha_t *)ctx, src, size); -} +int esp_sha384_update(esp_sha384_t *ctx, const void *src, size_t size); /** * @brief calculate input data for SHA512 @@ -228,20 +145,7 @@ static inline int esp_sha384_update(esp_sha384_t *ctx, const void *src, size_t s * * @return 0 if success or fail */ -static inline int esp_sha512_update(esp_sha512_t *ctx, const void *src, size_t size) -{ - return __esp_sha_update((esp_sha_t *)ctx, src, size); -} - -/** - * @brief output SHA(1/224/256/384/512) calculation result - * - * @param ctx SHA contex pointer - * @param dest output data buffer pointer - * - * @return 0 if success or fail - */ -int __esp_sha_finish(esp_sha_t *ctx, void *dest); +int esp_sha512_update(esp_sha512_t *ctx, const void *src, size_t size); /** * @brief output SHA1 calculation result @@ -251,10 +155,7 @@ int __esp_sha_finish(esp_sha_t *ctx, void *dest); * * @return 0 if success or fail */ -static inline int esp_sha1_finish(esp_sha1_t *ctx, void *dest) -{ - return __esp_sha_finish(ctx, dest); -} +int esp_sha1_finish(esp_sha1_t *ctx, void *dest); /** * @brief output SHA224 calculation result @@ -264,10 +165,7 @@ static inline int esp_sha1_finish(esp_sha1_t *ctx, void *dest) * * @return 0 if success or fail */ -static inline int esp_sha224_finish(esp_sha224_t *ctx, void *dest) -{ - return __esp_sha_finish(ctx, dest); -} +int esp_sha224_finish(esp_sha224_t *ctx, void *dest); /** * @brief output SHA256 calculation result @@ -277,10 +175,7 @@ static inline int esp_sha224_finish(esp_sha224_t *ctx, void *dest) * * @return 0 if success or fail */ -static inline int esp_sha256_finish(esp_sha256_t *ctx, void *dest) -{ - return __esp_sha_finish(ctx, dest); -} +int esp_sha256_finish(esp_sha256_t *ctx, void *dest); /** * @brief output SHA384 calculation result @@ -290,10 +185,7 @@ static inline int esp_sha256_finish(esp_sha256_t *ctx, void *dest) * * @return 0 if success or fail */ -static inline int esp_sha384_finish(esp_sha384_t *ctx, void *dest) -{ - return __esp_sha_finish((esp_sha_t *)ctx, dest); -} +int esp_sha384_finish(esp_sha384_t *ctx, void *dest); /** * @brief output SHA512 calculation result @@ -303,10 +195,7 @@ static inline int esp_sha384_finish(esp_sha384_t *ctx, void *dest) * * @return 0 if success or fail */ -static inline int esp_sha512_finish(esp_sha512_t *ctx, void *dest) -{ - return __esp_sha_finish((esp_sha_t *)ctx, dest); -} +int esp_sha512_finish(esp_sha512_t *ctx, void *dest); #ifdef __cplusplus } diff --git a/components/util/src/sha.c b/components/util/src/sha.c deleted file mode 100644 index 712cd4105..000000000 --- a/components/util/src/sha.c +++ /dev/null @@ -1,599 +0,0 @@ -// Copyright 2018 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 -#include -#include "util_assert.h" -#include -#include "esp_sha.h" -#include "esp_log.h" - -#define UL64(x) x##ULL - -#define F0(x, y, z) ((x & y) | (z & (x | y))) -#define F1(x, y, z) (z ^ (x & (y ^ z))) - -#define SHR(x, n) ((x & 0xFFFFFFFF) >> n) -#define ROTR(x, n) (SHR(x,n) | (x << (32 - n))) - -#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) -#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) - -#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) -#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) - -#define TAG "SHA" - -static const uint32_t sha_padding[] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const uint32_t __g_esp_sha1_state_ctx[] = { - 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 -}; - -const uint32_t __g_esp_sha224_state_ctx[] = { - 0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939, - 0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4 -}; - -const uint32_t __g_esp_sha256_state_ctx[] = { - 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, - 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 -}; - -const uint64_t __g_esp_sha384_state_ctx[] = { - 0xCBBB9D5DC1059ED8, 0x629A292A367CD507, 0x9159015A3070DD17, - 0x152FECD8F70E5939, 0x67332667FFC00B31, 0x8EB44A8768581511, - 0xDB0C2E0D64F98FA7, 0x47B5481DBEFA4FA4 -}; - -const uint64_t __g_esp_sha512_state_ctx[] = { - 0x6A09E667F3BCC908, 0xBB67AE8584CAA73B, 0x3C6EF372FE94F82B, - 0xA54FF53A5F1D36F1, 0x510E527FADE682D1, 0x9B05688C2B3E6C1F, - 0x1F83D9ABFB41BD6B, 0x5BE0CD19137E2179 -}; - -static void esp_sha_put_be(void *dest, const void *src, size_t size, size_t steps) -{ - uint8_t *d_buf = (uint8_t *)dest; - const uint8_t *s_buf = (const uint8_t *)src; - - for (int i = 0; i < size; i += steps) { - for (int j = 0; j < steps; j++) { - d_buf[i + j] = s_buf[i + (steps - j - 1)]; - } - } -} - -int __esp_sha1_process(void *in_ctx, const void *src) -{ - const uint8_t *data = (const uint8_t *)src; - esp_sha_t *ctx = (esp_sha_t *)in_ctx; - - uint32_t temp, W[16], A[5]; - - esp_sha_put_be(W, data, 64, sizeof(uint32_t)); - -#undef S -#undef R -#undef P -#undef F -#undef K - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define R(t) \ -( \ - temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \ - W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \ - ( W[t & 0x0F] = S(temp,1) ) \ -) - -#define P(a,b,c,d,e,x) \ -{ \ - e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ -} - - for (int i = 0; i < 5; i++) - A[i] = ctx->state[i]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) -#define K 0x5A827999 - - P( A[0], A[1], A[2], A[3], A[4], W[0] ); - P( A[4], A[0], A[1], A[2], A[3], W[1] ); - P( A[3], A[4], A[0], A[1], A[2], W[2] ); - P( A[2], A[3], A[4], A[0], A[1], W[3] ); - P( A[1], A[2], A[3], A[4], A[0], W[4] ); - P( A[0], A[1], A[2], A[3], A[4], W[5] ); - P( A[4], A[0], A[1], A[2], A[3], W[6] ); - P( A[3], A[4], A[0], A[1], A[2], W[7] ); - P( A[2], A[3], A[4], A[0], A[1], W[8] ); - P( A[1], A[2], A[3], A[4], A[0], W[9] ); - P( A[0], A[1], A[2], A[3], A[4], W[10] ); - P( A[4], A[0], A[1], A[2], A[3], W[11] ); - P( A[3], A[4], A[0], A[1], A[2], W[12] ); - P( A[2], A[3], A[4], A[0], A[1], W[13] ); - P( A[1], A[2], A[3], A[4], A[0], W[14] ); - P( A[0], A[1], A[2], A[3], A[4], W[15] ); - P( A[4], A[0], A[1], A[2], A[3], R(16) ); - P( A[3], A[4], A[0], A[1], A[2], R(17) ); - P( A[2], A[3], A[4], A[0], A[1], R(18) ); - P( A[1], A[2], A[3], A[4], A[0], R(19) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0x6ED9EBA1 - - P( A[0], A[1], A[2], A[3], A[4], R(20) ); - P( A[4], A[0], A[1], A[2], A[3], R(21) ); - P( A[3], A[4], A[0], A[1], A[2], R(22) ); - P( A[2], A[3], A[4], A[0], A[1], R(23) ); - P( A[1], A[2], A[3], A[4], A[0], R(24) ); - P( A[0], A[1], A[2], A[3], A[4], R(25) ); - P( A[4], A[0], A[1], A[2], A[3], R(26) ); - P( A[3], A[4], A[0], A[1], A[2], R(27) ); - P( A[2], A[3], A[4], A[0], A[1], R(28) ); - P( A[1], A[2], A[3], A[4], A[0], R(29) ); - P( A[0], A[1], A[2], A[3], A[4], R(30) ); - P( A[4], A[0], A[1], A[2], A[3], R(31) ); - P( A[3], A[4], A[0], A[1], A[2], R(32) ); - P( A[2], A[3], A[4], A[0], A[1], R(33) ); - P( A[1], A[2], A[3], A[4], A[0], R(34) ); - P( A[0], A[1], A[2], A[3], A[4], R(35) ); - P( A[4], A[0], A[1], A[2], A[3], R(36) ); - P( A[3], A[4], A[0], A[1], A[2], R(37) ); - P( A[2], A[3], A[4], A[0], A[1], R(38) ); - P( A[1], A[2], A[3], A[4], A[0], R(39) ); - -#undef K -#undef F - -#define F(x,y,z) ((x & y) | (z & (x | y))) -#define K 0x8F1BBCDC - - P( A[0], A[1], A[2], A[3], A[4], R(40) ); - P( A[4], A[0], A[1], A[2], A[3], R(41) ); - P( A[3], A[4], A[0], A[1], A[2], R(42) ); - P( A[2], A[3], A[4], A[0], A[1], R(43) ); - P( A[1], A[2], A[3], A[4], A[0], R(44) ); - P( A[0], A[1], A[2], A[3], A[4], R(45) ); - P( A[4], A[0], A[1], A[2], A[3], R(46) ); - P( A[3], A[4], A[0], A[1], A[2], R(47) ); - P( A[2], A[3], A[4], A[0], A[1], R(48) ); - P( A[1], A[2], A[3], A[4], A[0], R(49) ); - P( A[0], A[1], A[2], A[3], A[4], R(50) ); - P( A[4], A[0], A[1], A[2], A[3], R(51) ); - P( A[3], A[4], A[0], A[1], A[2], R(52) ); - P( A[2], A[3], A[4], A[0], A[1], R(53) ); - P( A[1], A[2], A[3], A[4], A[0], R(54) ); - P( A[0], A[1], A[2], A[3], A[4], R(55) ); - P( A[4], A[0], A[1], A[2], A[3], R(56) ); - P( A[3], A[4], A[0], A[1], A[2], R(57) ); - P( A[2], A[3], A[4], A[0], A[1], R(58) ); - P( A[1], A[2], A[3], A[4], A[0], R(59) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0xCA62C1D6 - - P( A[0], A[1], A[2], A[3], A[4], R(60) ); - P( A[4], A[0], A[1], A[2], A[3], R(61) ); - P( A[3], A[4], A[0], A[1], A[2], R(62) ); - P( A[2], A[3], A[4], A[0], A[1], R(63) ); - P( A[1], A[2], A[3], A[4], A[0], R(64) ); - P( A[0], A[1], A[2], A[3], A[4], R(65) ); - P( A[4], A[0], A[1], A[2], A[3], R(66) ); - P( A[3], A[4], A[0], A[1], A[2], R(67) ); - P( A[2], A[3], A[4], A[0], A[1], R(68) ); - P( A[1], A[2], A[3], A[4], A[0], R(69) ); - P( A[0], A[1], A[2], A[3], A[4], R(70) ); - P( A[4], A[0], A[1], A[2], A[3], R(71) ); - P( A[3], A[4], A[0], A[1], A[2], R(72) ); - P( A[2], A[3], A[4], A[0], A[1], R(73) ); - P( A[1], A[2], A[3], A[4], A[0], R(74) ); - P( A[0], A[1], A[2], A[3], A[4], R(75) ); - P( A[4], A[0], A[1], A[2], A[3], R(76) ); - P( A[3], A[4], A[0], A[1], A[2], R(77) ); - P( A[2], A[3], A[4], A[0], A[1], R(78) ); - P( A[1], A[2], A[3], A[4], A[0], R(79) ); - -#undef K -#undef F -#undef R -#undef P - - for (int i = 0; i < 5; i++) - ctx->state[i] += A[i]; - - return 0; -} - -int __esp_sha256_process(void *in_ctx, const void *src) -{ - const uint8_t *data = (const uint8_t *)src; - esp_sha_t *ctx = (esp_sha_t *)in_ctx; - uint32_t temp1, temp2, W[64]; - uint32_t A[8]; - -#undef R -#undef P - -#define R(t) \ -( \ - W[t] = S1(W[t - 2]) + W[t - 7] + \ - S0(W[t - 15]) + W[t - 16] \ -) - -#define P(a, b, c, d, e, f, g, h, x, K) \ -{ \ - temp1 = h + S3(e) + F1(e,f,g) + K + x; \ - temp2 = S2(a) + F0(a,b,c); \ - d += temp1; h = temp1 + temp2; \ -} - - static const uint32_t K[] = { - 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, - 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, - 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, - 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, - 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, - 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, - 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, - 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, - 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, - 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, - 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, - 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, - 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, - 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, - 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, - 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, - }; - - for (int i = 0; i < 8; i++) - A[i] = ctx->state[i]; - - for (int i = 0; i < 64; i++) { - if (i < 16) - esp_sha_put_be(&W[i], data + 4 * i, 4, sizeof(uint32_t)); - else - R(i); - - P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i]); - - temp1 = A[7]; - A[7] = A[6]; - A[6] = A[5]; - A[5] = A[4]; - A[4] = A[3]; - A[3] = A[2]; - A[2] = A[1]; - A[1] = A[0]; - A[0] = temp1; - } - - for (int i = 0; i < 8; i++) - ctx->state[i] += A[i]; - - return 0; - -#undef R -#undef P -} - -int __esp_sha512_process(void *in_ctx, const void *src) -{ - int i; - uint64_t temp1, temp2, W[80]; - uint64_t A[8]; - const uint8_t *data = (const uint8_t *)src; - esp_sha512_t *ctx = (esp_sha512_t *)in_ctx; - - static const uint64_t K[80] = - { - UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), - UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), - UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), - UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), - UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), - UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), - UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), - UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), - UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), - UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), - UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), - UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), - UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), - UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), - UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), - UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), - UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), - UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), - UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), - UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), - UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), - UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), - UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), - UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), - UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), - UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), - UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), - UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), - UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), - UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), - UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), - UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), - UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), - UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), - UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), - UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), - UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), - UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), - UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), - UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) - }; - -#undef SHR -#undef ROTR -#undef S0 -#undef S1 -#undef S2 -#undef S3 -#undef F0 -#undef F1 -#undef P - -#define SHR(x,n) (x >> n) -#define ROTR(x,n) (SHR(x,n) | (x << (64 - n))) - -#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) -#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6)) - -#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) -#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) - -#define F0(x,y,z) ((x & y) | (z & (x | y))) -#define F1(x,y,z) (z ^ (x & (y ^ z))) - -#define P(a,b,c,d,e,f,g,h,x,K) \ -{ \ - temp1 = h + S3(e) + F1(e,f,g) + K + x; \ - temp2 = S2(a) + F0(a,b,c); \ - d += temp1; h = temp1 + temp2; \ -} - - for (i = 0; i < 16; i++) { - esp_sha_put_be(&W[i], data + (i << 3), sizeof(uint64_t), sizeof(uint64_t)); - } - - for (; i < 80; i++) { - W[i] = S1(W[i - 2]) + W[i - 7] + - S0(W[i - 15]) + W[i - 16]; - } - - for (int j = 0; j < 8; j++) - A[j] = ctx->state[j]; - - i = 0; - do { - P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); i++; - P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i], K[i] ); i++; - P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i], K[i] ); i++; - P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i], K[i] ); i++; - P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i], K[i] ); i++; - P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i], K[i] ); i++; - P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i], K[i] ); i++; - P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i], K[i] ); i++; - } while (i < 80); - - for (int j = 0; j < 8; j++) - ctx->state[j] += A[j]; - - return 0; - -#undef SHR -#undef ROTR -#undef S0 -#undef S1 -#undef S2 -#undef S3 -#undef F0 -#undef F1 -#undef P -} - -/** - * @brief initialize the SHA1/SHA224/SHA256 contex - */ -int __esp_sha_init(esp_sha_t *ctx, esp_sha_type_t type, const uint32_t *state_ctx, size_t size, sha_cal_t sha_cal) -{ - util_assert(ctx); - - ctx->total[0] = 0; - ctx->total[1] = 0; - - for (int i = 0; i < size; i ++) - ctx->state[i] = state_ctx[i]; - - ctx->type = type; - ctx->sha_cal = sha_cal; - - return 0; -} - -/** - * @brief initialize the SHA512 contex - */ -int __esp_sha512_init(esp_sha512_t *ctx, esp_sha_type_t type, const uint64_t *state_ctx, size_t size) -{ - util_assert(ctx); - - ctx->total[0] = 0; - ctx->total[1] = 0; - - for (int i = 0; i < size; i ++) - ctx->state[i] = state_ctx[i]; - - ctx->type = type; - ctx->sha_cal = __esp_sha512_process; - - return 0; -} - -/** - * @brief input data which is calculated for SHA - */ -int __esp_sha_update(esp_sha_t *ctx, const void *src, size_t size) -{ - int ret; - size_t fill; - uint32_t left; - uint32_t step; - sha_cal_t sha_cal; - size_t ilen = size; - const uint8_t *input = (const uint8_t *)src; - - util_assert(ctx); - util_assert(src); - - if (ilen == 0) - return 0; - - if (SHA1 == ctx->type || SHA224 == ctx->type || SHA256 == ctx->type) { - left = ctx->total[0] & 0x3F; - - ctx->total[0] += (uint32_t)ilen; - if (ctx->total[0] < (uint32_t)ilen) - ctx->total[1]++; - - sha_cal = ctx->sha_cal; - step = 64; - } else { - esp_sha512_t *ctx512 = (esp_sha512_t *)ctx; - - left = (uint32_t)(ctx512->total[0] & 0x7F); - - ctx512->total[0] += ilen; - if (ctx512->total[0] < ilen) - ctx512->total[1]++; - - sha_cal = ctx512->sha_cal; - step = 128; - } - - fill = step - left; - - if (left && ilen >= fill) { - memcpy(ctx->buffer + left, input, fill); - - if ((ret = sha_cal(ctx, ctx->buffer)) != 0) - return ret; - - input += fill; - ilen -= fill; - left = 0; - } - - while (ilen >= step) { - ret = sha_cal(ctx, input); - if (ret) - return ret; - - input += step; - ilen -= step; - } - - if (ilen > 0) - memcpy(ctx->buffer + left, input, ilen); - - return 0; -} - -/** - * @brief input data which is calculated for SHA - */ -int __esp_sha_finish(esp_sha_t *ctx, void *dest) -{ - int ret; - size_t bytes = 0; - uint32_t last, padn; - uint64_t high, low; - uint8_t *output = dest; - size_t step; - void *state; - uint8_t msglen[16]; - - util_assert(ctx); - util_assert(dest); - - if (SHA1 == ctx->type) - bytes = 20; - else if (SHA224 == ctx->type) - bytes = 28; - else if (SHA256 == ctx->type) - bytes = 32; - else if (SHA384 == ctx->type) - bytes = 48; - else if (SHA512 == ctx->type) - bytes = 64; - - if (SHA1 == ctx->type || SHA224 == ctx->type || SHA256 == ctx->type) { - high = (ctx->total[0] >> 29) - | (ctx->total[1] << 3); - - low = (ctx->total[0] << 3); - - last = ctx->total[0] & 0x3F; - padn = (last < 56) ? (56 - last) : (120 - last); - - step = 4; - state = ctx->state; - } else { - esp_sha512_t *ctx512 = (esp_sha512_t *)ctx; - - high = (ctx512->total[0] >> 61) - | (ctx512->total[1] << 3); - - low = (ctx512->total[0] << 3); - - last = (size_t)(ctx512->total[0] & 0x7F); - padn = (last < 112) ? (112 - last) : (240 - last); - - step = 8; - state = ctx512->state; - } - - esp_sha_put_be(msglen, &high, step, step); - esp_sha_put_be(msglen + step, &low, step, step); - - ret = __esp_sha_update(ctx, sha_padding, padn); - if (ret) - return ret; - - ret = __esp_sha_update(ctx, msglen, step * 2); - if (ret) - return ret; - - esp_sha_put_be(output, state, bytes, step); - - return 0; -} - diff --git a/components/util/src/sha1.c b/components/util/src/sha1.c new file mode 100644 index 000000000..3f10ef385 --- /dev/null +++ b/components/util/src/sha1.c @@ -0,0 +1,165 @@ +// Copyright 2018 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 +#include +#include "util_assert.h" +#include +#include "esp_sha.h" +#include "esp_log.h" + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \ + (rol(block->l[i], 8) & 0x00FF00FF)) + +#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \ + block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1)) + +#define R0(v,w,x,y,z,i) \ + z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \ + w = rol(w, 30); +#define R1(v,w,x,y,z,i) \ + z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \ + w = rol(w, 30); +#define R2(v,w,x,y,z,i) \ + z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30); +#define R3(v,w,x,y,z,i) \ + z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \ + w = rol(w, 30); +#define R4(v,w,x,y,z,i) \ + z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \ + w=rol(w, 30); + +typedef union { + uint8_t c[64]; + uint32_t l[16]; +} block_t; + +static void esp_sha1_transform(uint32_t state[5], const uint8_t buffer[64]) +{ + uint32_t a, b, c, d, e; + block_t workspace; + block_t *block = &workspace; + + memcpy(block, buffer, 64); + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; +} + +int esp_sha1_init(esp_sha1_t *ctx) +{ + util_assert(ctx); + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; + + ctx->total[0] = ctx->total[1] = 0; + + return 0; +} + +int esp_sha1_update(esp_sha1_t *ctx, const void *src, size_t size) +{ + uint32_t i, j; + const uint8_t *data = (const uint8_t *)src; + + util_assert(ctx); + util_assert(src); + util_assert(size); + + j = (ctx->total[0] >> 3) & 63; + + if ((ctx->total[0] += size << 3) < (size << 3)) + ctx->total[1]++; + + ctx->total[1] += (size >> 29); + + if ((j + size) > 63) { + memcpy(&ctx->buffer[j], data, (i = 64-j)); + + esp_sha1_transform(ctx->state, ctx->buffer); + for ( ; i + 63 < size; i += 64) + esp_sha1_transform(ctx->state, &data[i]); + + j = 0; + } else + i = 0; + + memcpy(&ctx->buffer[j], &data[i], size - i); + + return 0; +} + +int esp_sha1_finish(esp_sha1_t *ctx, void *dest) +{ + uint32_t i; + uint32_t index; + uint8_t finalcount[8]; + uint8_t *digest = (uint8_t *)dest; + + util_assert(ctx); + util_assert(dest); + + for (i = 0; i < 8; i++) + finalcount[i] = (uint8_t)((ctx->total[(i >= 4 ? 0 : 1)] >> ((3-(i & 3)) * 8) ) & 255); + + index = 0x80; + esp_sha1_update(ctx, (uint8_t *)&index, 1); + + while ((ctx->total[0] & 504) != 448) { + index = 0; + esp_sha1_update(ctx, (uint8_t *)&index, 1); + } + esp_sha1_update(ctx, finalcount, 8); + + for (i = 0; i < 20; i++) + digest[i] = (uint8_t)((ctx->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); + + return 0; +} diff --git a/components/util/src/sha256.c b/components/util/src/sha256.c new file mode 100644 index 000000000..3b658beb9 --- /dev/null +++ b/components/util/src/sha256.c @@ -0,0 +1,252 @@ +// Copyright 2018 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 +#include +#include "util_assert.h" +#include +#include "esp_sha.h" +#include "esp_log.h" + +#define ESP_GET_BE32(a) ((((uint32_t) (a)[0]) << 24) | (((uint32_t) (a)[1]) << 16) | \ + (((uint32_t) (a)[2]) << 8) | ((uint32_t) (a)[3])) + +#define ESP_PUT_BE64(a, val) \ + do { \ + (a)[0] = (uint8_t) (((uint64_t) (val)) >> 56); \ + (a)[1] = (uint8_t) (((uint64_t) (val)) >> 48); \ + (a)[2] = (uint8_t) (((uint64_t) (val)) >> 40); \ + (a)[3] = (uint8_t) (((uint64_t) (val)) >> 32); \ + (a)[4] = (uint8_t) (((uint64_t) (val)) >> 24); \ + (a)[5] = (uint8_t) (((uint64_t) (val)) >> 16); \ + (a)[6] = (uint8_t) (((uint64_t) (val)) >> 8); \ + (a)[7] = (uint8_t) (((uint64_t) (val)) & 0xff); \ + } while (0) + +#define ESP_PUT_BE32(a, val) \ + do { \ + (a)[0] = (uint8_t) ((((uint32_t) (val)) >> 24) & 0xff); \ + (a)[1] = (uint8_t) ((((uint32_t) (val)) >> 16) & 0xff); \ + (a)[2] = (uint8_t) ((((uint32_t) (val)) >> 8) & 0xff); \ + (a)[3] = (uint8_t) (((uint32_t) (val)) & 0xff); \ + } while (0) + +#define RORc(x, y) \ +( ((((uint32_t) (x) & 0xFFFFFFFFUL) >> (uint32_t) ((y) & 31)) | \ + ((uint32_t) (x) << (uint32_t) (32 - ((y) & 31)))) & 0xFFFFFFFFUL) +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) RORc((x), (n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif + +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + +static const uint32_t K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +static void esp_sha256_transform(esp_sha256_t *ctx, const uint8_t *buf) +{ + uint32_t S[8], W[64], t0, t1; + uint32_t t; + int i; + + for (i = 0; i < 8; i++) + S[i] = ctx->state[i]; + + for (i = 0; i < 16; i++) + W[i] = ESP_GET_BE32(buf + (4 * i)); + + for (i = 16; i < 64; i++) + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + + for (i = 0; i < 64; ++i) { + RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); + t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; + S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; + } + + for (i = 0; i < 8; i++) + ctx->state[i] = ctx->state[i] + S[i]; +} + +int esp_sha256_init(esp_sha256_t *ctx) +{ + util_assert(ctx); + + ctx->is224 = 0; + + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x6A09E667UL; + ctx->state[1] = 0xBB67AE85UL; + ctx->state[2] = 0x3C6EF372UL; + ctx->state[3] = 0xA54FF53AUL; + ctx->state[4] = 0x510E527FUL; + ctx->state[5] = 0x9B05688CUL; + ctx->state[6] = 0x1F83D9ABUL; + ctx->state[7] = 0x5BE0CD19UL; + + return 0; +} + +int esp_sha224_init(esp_sha224_t *ctx) +{ + util_assert(ctx); + + ctx->is224 = 1; + + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0xC1059ED8; + ctx->state[1] = 0x367CD507; + ctx->state[2] = 0x3070DD17; + ctx->state[3] = 0xF70E5939; + ctx->state[4] = 0xFFC00B31; + ctx->state[5] = 0x68581511; + ctx->state[6] = 0x64F98FA7; + ctx->state[7] = 0xBEFA4FA4; + + return 0; +} + +int esp_sha256_update(esp_sha256_t *ctx, const void *src, size_t size) +{ + size_t fill; + uint32_t left; + const uint8_t *input = (const uint8_t *)src; + + util_assert(ctx); + util_assert(src); + util_assert(size); + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += size; + ctx->total[0] &= 0xFFFFFFFF; + + if (ctx->total[0] < size) + ctx->total[1]++; + + if (left && size >= fill) { + memcpy(ctx->buffer + left, input, fill); + + esp_sha256_transform(ctx, ctx->buffer); + + input += fill; + size -= fill; + left = 0; + } + + while (size >= 64) { + esp_sha256_transform(ctx, input); + + input += 64; + size -= 64; + } + + if (size > 0) + memcpy(ctx->buffer + left, input, size); + + return 0; +} + +int esp_sha224_update(esp_sha224_t *ctx, const void *src, size_t size) +{ + util_assert(ctx); + util_assert(src); + util_assert(size); + + return esp_sha256_update(ctx, src, size); +} + +int esp_sha224_finish(esp_sha224_t *ctx, void *dest) +{ + uint32_t used; + uint32_t high, low; + uint8_t *out = (uint8_t *)dest; + + util_assert(ctx); + util_assert(dest); + + used = ctx->total[0] & 0x3F; + + ctx->buffer[used++] = 0x80; + + if (used <= 56) { + memset(ctx->buffer + used, 0, 56 - used); + } else { + memset(ctx->buffer + used, 0, 64 - used); + esp_sha256_transform(ctx, ctx->buffer); + memset(ctx->buffer, 0, 56); + } + + high = (ctx->total[0] >> 29) | (ctx->total[1] << 3); + low = (ctx->total[0] << 3); + + ESP_PUT_BE32(ctx->buffer + 56, high); + ESP_PUT_BE32(ctx->buffer + 60, low); + + esp_sha256_transform(ctx, ctx->buffer); + + ESP_PUT_BE32(out + 0, ctx->state[0]); + ESP_PUT_BE32(out + 4, ctx->state[1]); + ESP_PUT_BE32(out + 8, ctx->state[2]); + ESP_PUT_BE32(out + 12, ctx->state[3]); + ESP_PUT_BE32(out + 16, ctx->state[4]); + ESP_PUT_BE32(out + 20, ctx->state[5]); + ESP_PUT_BE32(out + 24, ctx->state[6]); + + if (!ctx->is224) { + ESP_PUT_BE32(out + 28, ctx->state[7]); + } + + return( 0 ); +} + +int esp_sha256_finish(esp_sha256_t *ctx, void *dest) +{ + util_assert(ctx); + util_assert(dest); + + esp_sha224_finish(ctx, dest); + + return 0; +} diff --git a/components/util/src/sha512.c b/components/util/src/sha512.c new file mode 100644 index 000000000..61faf2c18 --- /dev/null +++ b/components/util/src/sha512.c @@ -0,0 +1,302 @@ +// Copyright 2018 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 +#include +#include "util_assert.h" +#include +#include "esp_sha.h" +#include "esp_log.h" + +#define UL64(x) x##ULL + +#define SHR(x,n) ((x) >> (n)) +#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n)))) + +#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) +#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6)) + +#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) +#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) + +#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) +#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) + +#define P(a,b,c,d,e,f,g,h,x,K) \ + do \ + { \ + temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ + temp2 = S2(a) + F0((a),(b),(c)); \ + (d) += temp1; (h) = temp1 + temp2; \ + } while( 0 ) + +#define GET_UINT64_BE(n,b,i) \ +{ \ + (n) = ( (uint64_t) (b)[(i) ] << 56 ) \ + | ( (uint64_t) (b)[(i) + 1] << 48 ) \ + | ( (uint64_t) (b)[(i) + 2] << 40 ) \ + | ( (uint64_t) (b)[(i) + 3] << 32 ) \ + | ( (uint64_t) (b)[(i) + 4] << 24 ) \ + | ( (uint64_t) (b)[(i) + 5] << 16 ) \ + | ( (uint64_t) (b)[(i) + 6] << 8 ) \ + | ( (uint64_t) (b)[(i) + 7] ); \ +} + +#define PUT_UINT64_BE(n,b,i) \ +{ \ + (b)[(i) ] = (uint8_t) ( (n) >> 56 ); \ + (b)[(i) + 1] = (uint8_t) ( (n) >> 48 ); \ + (b)[(i) + 2] = (uint8_t) ( (n) >> 40 ); \ + (b)[(i) + 3] = (uint8_t) ( (n) >> 32 ); \ + (b)[(i) + 4] = (uint8_t) ( (n) >> 24 ); \ + (b)[(i) + 5] = (uint8_t) ( (n) >> 16 ); \ + (b)[(i) + 6] = (uint8_t) ( (n) >> 8 ); \ + (b)[(i) + 7] = (uint8_t) ( (n) ); \ +} + +static const uint64_t K[80] = +{ + UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), + UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), + UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), + UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), + UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), + UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), + UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), + UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), + UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), + UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), + UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), + UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), + UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), + UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), + UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), + UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), + UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), + UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), + UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), + UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), + UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), + UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), + UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), + UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), + UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), + UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), + UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), + UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), + UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), + UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), + UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), + UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), + UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), + UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), + UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), + UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), + UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), + UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), + UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), + UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) +}; + +static int esp_sha512_transform(esp_sha512_t *ctx, const uint8_t *data) +{ + int i; + uint64_t temp1, temp2, W[80]; + uint64_t A, B, C, D, E, F, G, H; + + for( i = 0; i < 16; i++ ) { + GET_UINT64_BE(W[i], data, i << 3); + } + + for( ; i < 80; i++ ) + W[i] = S1(W[i - 2]) + W[i - 7] + S0(W[i - 15]) + W[i - 16]; + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + F = ctx->state[5]; + G = ctx->state[6]; + H = ctx->state[7]; + i = 0; + + do { + P(A, B, C, D, E, F, G, H, W[i], K[i]); i++; + P(H, A, B, C, D, E, F, G, W[i], K[i]); i++; + P(G, H, A, B, C, D, E, F, W[i], K[i]); i++; + P(F, G, H, A, B, C, D, E, W[i], K[i]); i++; + P(E, F, G, H, A, B, C, D, W[i], K[i]); i++; + P(D, E, F, G, H, A, B, C, W[i], K[i]); i++; + P(C, D, E, F, G, H, A, B, W[i], K[i]); i++; + P(B, C, D, E, F, G, H, A, W[i], K[i]); i++; + } while (i < 80); + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; + ctx->state[5] += F; + ctx->state[6] += G; + ctx->state[7] += H; + + return( 0 ); +} + +int esp_sha512_init(esp_sha512_t *ctx) +{ + util_assert(ctx); + + ctx->is384 = 0; + + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = UL64(0x6A09E667F3BCC908); + ctx->state[1] = UL64(0xBB67AE8584CAA73B); + ctx->state[2] = UL64(0x3C6EF372FE94F82B); + ctx->state[3] = UL64(0xA54FF53A5F1D36F1); + ctx->state[4] = UL64(0x510E527FADE682D1); + ctx->state[5] = UL64(0x9B05688C2B3E6C1F); + ctx->state[6] = UL64(0x1F83D9ABFB41BD6B); + ctx->state[7] = UL64(0x5BE0CD19137E2179); + + return 0; +} + +int esp_sha384_init(esp_sha384_t *ctx) +{ + util_assert(ctx); + + ctx->is384 = 1; + + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = UL64(0xCBBB9D5DC1059ED8); + ctx->state[1] = UL64(0x629A292A367CD507); + ctx->state[2] = UL64(0x9159015A3070DD17); + ctx->state[3] = UL64(0x152FECD8F70E5939); + ctx->state[4] = UL64(0x67332667FFC00B31); + ctx->state[5] = UL64(0x8EB44A8768581511); + ctx->state[6] = UL64(0xDB0C2E0D64F98FA7); + ctx->state[7] = UL64(0x47B5481DBEFA4FA4); + + return 0; +} + +int esp_sha512_update(esp_sha512_t *ctx, const void *src, size_t size) +{ + size_t fill; + uint32_t left; + const uint8_t *input = (const uint8_t *)src; + + util_assert(ctx); + util_assert(src); + util_assert(size); + + left = (uint32_t) (ctx->total[0] & 0x7F); + fill = 128 - left; + + ctx->total[0] += (uint64_t)size; + + if( ctx->total[0] < (uint64_t)size) + ctx->total[1]++; + + if (left && size >= fill) { + memcpy(ctx->buffer + left, input, fill); + + esp_sha512_transform(ctx, ctx->buffer); + + input += fill; + size -= fill; + left = 0; + } + + while (size >= 128) { + esp_sha512_transform(ctx, input); + + input += 128; + size -= 128; + } + + if (size > 0) + memcpy((void *) (ctx->buffer + left), input, size); + + return( 0 ); +} + +int esp_sha384_update(esp_sha384_t *ctx, const void *src, size_t size) +{ + util_assert(ctx); + util_assert(src); + util_assert(size); + + return esp_sha512_update(ctx, src, size); +} + +int esp_sha384_finish(esp_sha384_t *ctx, void *dest) +{ + uint8_t used; + uint64_t high, low; + uint8_t *output = (uint8_t *)dest; + + util_assert(ctx); + util_assert(dest); + + used = ctx->total[0] & 0x7F; + + ctx->buffer[used++] = 0x80; + + if (used <= 112) + memset(ctx->buffer + used, 0, 112 - used); + else { + memset(ctx->buffer + used, 0, 128 - used); + esp_sha512_transform(ctx, ctx->buffer); + memset(ctx->buffer, 0, 112); + } + + high = (ctx->total[0] >> 61) | (ctx->total[1] << 3); + low = (ctx->total[0] << 3); + + PUT_UINT64_BE(high, ctx->buffer, 112); + PUT_UINT64_BE(low, ctx->buffer, 120); + + esp_sha512_transform(ctx, ctx->buffer); + + PUT_UINT64_BE(ctx->state[0], output, 0); + PUT_UINT64_BE(ctx->state[1], output, 8); + PUT_UINT64_BE(ctx->state[2], output, 16); + PUT_UINT64_BE(ctx->state[3], output, 24); + PUT_UINT64_BE(ctx->state[4], output, 32); + PUT_UINT64_BE(ctx->state[5], output, 40); + + if (!ctx->is384) { + PUT_UINT64_BE(ctx->state[6], output, 48); + PUT_UINT64_BE(ctx->state[7], output, 56); + } + + return 0; +} + +int esp_sha512_finish(esp_sha512_t *ctx, void *dest) +{ + util_assert(ctx); + util_assert(dest); + + esp_sha384_finish(ctx, dest); + + return 0; +} diff --git a/components/wpa_supplicant/include/crypto/sha1_i.h b/components/wpa_supplicant/include/crypto/sha1_i.h index 9b76fad8b..a9cc36544 100644 --- a/components/wpa_supplicant/include/crypto/sha1_i.h +++ b/components/wpa_supplicant/include/crypto/sha1_i.h @@ -19,7 +19,7 @@ #ifdef CONFIG_ESP_SHA #include "esp_sha.h" -typedef esp_sha_t SHA1_CTX; +typedef esp_sha1_t SHA1_CTX; #define SHA1Init(_sha) esp_sha1_init(_sha) #define SHA1Update(_sha, _s, _l) esp_sha1_update(_sha, _s, _l) diff --git a/components/wpa_supplicant/src/crypto/sha256-internal.c b/components/wpa_supplicant/src/crypto/sha256-internal.c index 8e56bdf8d..62d76b160 100644 --- a/components/wpa_supplicant/src/crypto/sha256-internal.c +++ b/components/wpa_supplicant/src/crypto/sha256-internal.c @@ -23,11 +23,11 @@ #ifdef CONFIG_ESP_SHA #include "esp_sha.h" -typedef esp_sha_t sha256_state_t; +typedef esp_sha256_t sha256_state_t; #define sha256_init(_sha) esp_sha256_init(_sha) #define sha256_process(_sha, _s, _l) esp_sha256_update(_sha, _s, _l) -#define sha256_done(_sha, _d) esp_sha1_finish(_sha, _d) +#define sha256_done(_sha, _d) esp_sha256_finish(_sha, _d) #else /* CONFIG_ESP_SHA */ #define SHA256_BLOCK_SIZE 64 diff --git a/docs/en/general-notes/index.rst b/docs/en/general-notes/index.rst index 46cd69bf0..77bbc5a85 100755 --- a/docs/en/general-notes/index.rst +++ b/docs/en/general-notes/index.rst @@ -24,3 +24,14 @@ We split the native OTA example into several sub-examples to let custemors to ch ^^^^^^^^^^^^^^^^^^ For better compatibility, the SDK is in bg mode by default. And application can set it to be bgn mode for reconnecting when it fails to connect some 11n only APs, refer to the `examples/wifi/simple_wifi `_. + +4. JTAG I/O +^^^^^^^^^^^ + +In some cases, if enable JTAG I/O (default options), it will cost some more current so that the hardware will cost more power. +So if users don't use Jtag or these GPIOs directly and want to save more power, please enable this option in the menuconfig: + +:: + + "Bootloader config ---> + [ ] Bootloader disable JTAG I/O" diff --git a/docs/requirements.txt b/docs/requirements.txt index 3676a3c39..f3884f2ee 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -5,9 +5,13 @@ sphinx>=1.8.4 breathe==4.11.1 sphinx-rtd-theme sphinx-notfound-page -sphinxcontrib-blockdiag>=1.5.5 -sphinxcontrib-seqdiag>=0.8.5 -sphinxcontrib-actdiag>=0.8.5 -sphinxcontrib-nwdiag>=0.9.5 +sphinxcontrib-blockdiag>=1.5.5, <2.0.0 +sphinxcontrib-seqdiag>=0.8.5, <2.0.0 +sphinxcontrib-actdiag>=0.8.5, <2.0.0 +sphinxcontrib-nwdiag>=0.9.5, <2.0.0 +blockdiag>=1.5.4, <2.0.0 +seqdiag>=0.9.6, <2.0.0 +actdiag>=0.5.4, <2.0.0 +nwdiag>=1.0.4, <2.0.0 recommonmark future>=0.16.0 # for ../tools/gen_esp_err_to_name.py diff --git a/examples/common_components/protocol_examples_common/connect.c b/examples/common_components/protocol_examples_common/connect.c index 5b6b28147..8d8c628ab 100644 --- a/examples/common_components/protocol_examples_common/connect.c +++ b/examples/common_components/protocol_examples_common/connect.c @@ -66,7 +66,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(s_connect_event_group, GOT_IPV4_BIT); diff --git a/examples/protocols/aws_iot/subscribe_publish/main/subscribe_publish_sample.c b/examples/protocols/aws_iot/subscribe_publish/main/subscribe_publish_sample.c index 5beaf0863..0bf17bb05 100644 --- a/examples/protocols/aws_iot/subscribe_publish/main/subscribe_publish_sample.c +++ b/examples/protocols/aws_iot/subscribe_publish/main/subscribe_publish_sample.c @@ -127,7 +127,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/aws_iot/thing_shadow/main/thing_shadow_sample.c b/examples/protocols/aws_iot/thing_shadow/main/thing_shadow_sample.c index 47403628f..f44469787 100644 --- a/examples/protocols/aws_iot/thing_shadow/main/thing_shadow_sample.c +++ b/examples/protocols/aws_iot/thing_shadow/main/thing_shadow_sample.c @@ -144,7 +144,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/coap_client/main/coap_client_example_main.c b/examples/protocols/coap_client/main/coap_client_example_main.c index f28df68dc..7d0a54348 100644 --- a/examples/protocols/coap_client/main/coap_client_example_main.c +++ b/examples/protocols/coap_client/main/coap_client_example_main.c @@ -173,7 +173,7 @@ static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/coap_server/main/coap_server_example_main.c b/examples/protocols/coap_server/main/coap_server_example_main.c index 9ec2be392..28860c153 100644 --- a/examples/protocols/coap_server/main/coap_server_example_main.c +++ b/examples/protocols/coap_server/main/coap_server_example_main.c @@ -159,7 +159,7 @@ static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/esp-mqtt/ssl/main/app_main.c b/examples/protocols/esp-mqtt/ssl/main/app_main.c index 17818e4e4..9830f5a70 100644 --- a/examples/protocols/esp-mqtt/ssl/main/app_main.c +++ b/examples/protocols/esp-mqtt/ssl/main/app_main.c @@ -44,7 +44,7 @@ static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/esp-mqtt/ssl_mutual_auth/main/app_main.c b/examples/protocols/esp-mqtt/ssl_mutual_auth/main/app_main.c index adf5db9a9..c26498c6c 100644 --- a/examples/protocols/esp-mqtt/ssl_mutual_auth/main/app_main.c +++ b/examples/protocols/esp-mqtt/ssl_mutual_auth/main/app_main.c @@ -44,7 +44,7 @@ static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/esp-mqtt/tcp/main/app_main.c b/examples/protocols/esp-mqtt/tcp/main/app_main.c index ea37a7409..08e245887 100644 --- a/examples/protocols/esp-mqtt/tcp/main/app_main.c +++ b/examples/protocols/esp-mqtt/tcp/main/app_main.c @@ -90,7 +90,7 @@ static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/esp-mqtt/ws/main/app_main.c b/examples/protocols/esp-mqtt/ws/main/app_main.c index 6b1e18c8a..d26299e91 100644 --- a/examples/protocols/esp-mqtt/ws/main/app_main.c +++ b/examples/protocols/esp-mqtt/ws/main/app_main.c @@ -87,7 +87,7 @@ static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/esp-mqtt/wss/main/app_main.c b/examples/protocols/esp-mqtt/wss/main/app_main.c index 06f6307dc..4bd39116e 100644 --- a/examples/protocols/esp-mqtt/wss/main/app_main.c +++ b/examples/protocols/esp-mqtt/wss/main/app_main.c @@ -44,7 +44,7 @@ static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/esp_http_client/main/app_wifi.c b/examples/protocols/esp_http_client/main/app_wifi.c index 7d8d8d971..9c679d220 100644 --- a/examples/protocols/esp_http_client/main/app_wifi.c +++ b/examples/protocols/esp_http_client/main/app_wifi.c @@ -43,7 +43,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/http_request/main/http_request_example_main.c b/examples/protocols/http_request/main/http_request_example_main.c index 23266c336..27bc42002 100644 --- a/examples/protocols/http_request/main/http_request_example_main.c +++ b/examples/protocols/http_request/main/http_request_example_main.c @@ -67,7 +67,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/http_server/advanced_tests/main/main.c b/examples/protocols/http_server/advanced_tests/main/main.c index 48dead086..7fd75a546 100644 --- a/examples/protocols/http_server/advanced_tests/main/main.c +++ b/examples/protocols/http_server/advanced_tests/main/main.c @@ -44,7 +44,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } ESP_ERROR_CHECK(esp_wifi_connect()); diff --git a/examples/protocols/http_server/persistent_sockets/main/main.c b/examples/protocols/http_server/persistent_sockets/main/main.c index 4bebbed85..a0413fed7 100644 --- a/examples/protocols/http_server/persistent_sockets/main/main.c +++ b/examples/protocols/http_server/persistent_sockets/main/main.c @@ -216,7 +216,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } ESP_ERROR_CHECK(esp_wifi_connect()); diff --git a/examples/protocols/http_server/simple/main/main.c b/examples/protocols/http_server/simple/main/main.c index d29ccaacd..f7cd5b0a5 100644 --- a/examples/protocols/http_server/simple/main/main.c +++ b/examples/protocols/http_server/simple/main/main.c @@ -243,7 +243,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } ESP_ERROR_CHECK(esp_wifi_connect()); diff --git a/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c b/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c index c2879f555..6c5f0a75b 100644 --- a/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c +++ b/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c @@ -104,7 +104,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/https_request/main/https_request_example_main.c b/examples/protocols/https_request/main/https_request_example_main.c index 628410ce5..7252e9ca6 100644 --- a/examples/protocols/https_request/main/https_request_example_main.c +++ b/examples/protocols/https_request/main/https_request_example_main.c @@ -98,7 +98,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); @@ -178,12 +178,7 @@ static void https_get_task(void *pvParameters) bzero(buf, sizeof(buf)); ret = esp_tls_conn_read(tls, (char *)buf, len); - if -#if CONFIG_SSL_USING_MBEDTLS - (ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == MBEDTLS_ERR_SSL_WANT_READ) -#else - (ret == WOLFSSL_ERROR_WANT_READ && ret == WOLFSSL_ERROR_WANT_WRITE) -#endif + if (ret == ESP_TLS_ERR_SSL_WANT_READ || ret == ESP_TLS_ERR_SSL_WANT_WRITE) continue; if(ret < 0) diff --git a/examples/protocols/https_request/sdkconfig.ci b/examples/protocols/https_request/sdkconfig.ci new file mode 100644 index 000000000..253c1c011 --- /dev/null +++ b/examples/protocols/https_request/sdkconfig.ci @@ -0,0 +1,3 @@ +CONFIG_LWIP_IPV6=y + +CONFIG_ESP_TLS_SERVER=y diff --git a/examples/protocols/ibm-mqtt/main/MQTTEcho.c b/examples/protocols/ibm-mqtt/main/MQTTEcho.c index dcddaaf7b..d7c61f227 100644 --- a/examples/protocols/ibm-mqtt/main/MQTTEcho.c +++ b/examples/protocols/ibm-mqtt/main/MQTTEcho.c @@ -62,7 +62,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/ibm-mqtt/sdkconfig.defaults b/examples/protocols/ibm-mqtt/sdkconfig.defaults index 9e0871e0b..93ec30db6 100644 --- a/examples/protocols/ibm-mqtt/sdkconfig.defaults +++ b/examples/protocols/ibm-mqtt/sdkconfig.defaults @@ -6,6 +6,7 @@ CONFIG_MQTT_PUBLISH_INTERVAL=0 # # ECLIPSE-MQTT # +CONFIG_MQTT_USING_IBM=y CONFIG_MQTT_KEEP_ALIVE=30 CONFIG_CLEAN_SESSION=y CONFIG_KEEP_SESSION= diff --git a/examples/protocols/mdns/main/mdns_example_main.c b/examples/protocols/mdns/main/mdns_example_main.c index bac352da2..921d70764 100644 --- a/examples/protocols/mdns/main/mdns_example_main.c +++ b/examples/protocols/mdns/main/mdns_example_main.c @@ -70,7 +70,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); } diff --git a/examples/protocols/openssl_client/main/openssl_client_example_main.c b/examples/protocols/openssl_client/main/openssl_client_example_main.c index 29c6f494f..28ca8befb 100644 --- a/examples/protocols/openssl_client/main/openssl_client_example_main.c +++ b/examples/protocols/openssl_client/main/openssl_client_example_main.c @@ -89,7 +89,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/openssl_demo/main/openssl_demo_example_main.c b/examples/protocols/openssl_demo/main/openssl_demo_example_main.c index a52425420..a17cb846f 100644 --- a/examples/protocols/openssl_demo/main/openssl_demo_example_main.c +++ b/examples/protocols/openssl_demo/main/openssl_demo_example_main.c @@ -76,7 +76,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/openssl_server/main/openssl_server_example_main.c b/examples/protocols/openssl_server/main/openssl_server_example_main.c index 7431e8a48..0ff14f851 100644 --- a/examples/protocols/openssl_server/main/openssl_server_example_main.c +++ b/examples/protocols/openssl_server/main/openssl_server_example_main.c @@ -89,7 +89,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/sntp/main/sntp_example_main.c b/examples/protocols/sntp/main/sntp_example_main.c index 50687a26b..f9a91b2e0 100644 --- a/examples/protocols/sntp/main/sntp_example_main.c +++ b/examples/protocols/sntp/main/sntp_example_main.c @@ -88,7 +88,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/protocols/sockets/tcp_client/main/tcp_client.c b/examples/protocols/sockets/tcp_client/main/tcp_client.c index cd546ddbc..83d2dd860 100644 --- a/examples/protocols/sockets/tcp_client/main/tcp_client.c +++ b/examples/protocols/sockets/tcp_client/main/tcp_client.c @@ -74,7 +74,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT); diff --git a/examples/protocols/sockets/tcp_server/main/tcp_server.c b/examples/protocols/sockets/tcp_server/main/tcp_server.c index d7c6472ab..334bbff40 100644 --- a/examples/protocols/sockets/tcp_server/main/tcp_server.c +++ b/examples/protocols/sockets/tcp_server/main/tcp_server.c @@ -67,7 +67,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT); diff --git a/examples/protocols/sockets/udp_client/main/udp_client.c b/examples/protocols/sockets/udp_client/main/udp_client.c index 79f9aaa5b..361f0749f 100644 --- a/examples/protocols/sockets/udp_client/main/udp_client.c +++ b/examples/protocols/sockets/udp_client/main/udp_client.c @@ -74,7 +74,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT); diff --git a/examples/protocols/sockets/udp_multicast/main/udp_multicast_example_main.c b/examples/protocols/sockets/udp_multicast/main/udp_multicast_example_main.c index 5dea3f6a7..b7e42dcda 100644 --- a/examples/protocols/sockets/udp_multicast/main/udp_multicast_example_main.c +++ b/examples/protocols/sockets/udp_multicast/main/udp_multicast_example_main.c @@ -79,7 +79,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT); diff --git a/examples/protocols/sockets/udp_server/main/udp_server.c b/examples/protocols/sockets/udp_server/main/udp_server.c index 2e81d0c51..d5a405060 100644 --- a/examples/protocols/sockets/udp_server/main/udp_server.c +++ b/examples/protocols/sockets/udp_server/main/udp_server.c @@ -67,7 +67,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT); diff --git a/examples/provisioning/custom_config/main/app_prov.c b/examples/provisioning/custom_config/main/app_prov.c index ad7253e30..64403ce52 100644 --- a/examples/provisioning/custom_config/main/app_prov.c +++ b/examples/provisioning/custom_config/main/app_prov.c @@ -217,7 +217,7 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event) g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); } diff --git a/examples/provisioning/softap_prov/main/app_prov.c b/examples/provisioning/softap_prov/main/app_prov.c index 864fe7fc4..495c08992 100644 --- a/examples/provisioning/softap_prov/main/app_prov.c +++ b/examples/provisioning/softap_prov/main/app_prov.c @@ -200,7 +200,7 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event) default: if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } /* If none of the expected reasons, * retry connecting to host SSID */ diff --git a/examples/system/console/main/cmd_wifi.c b/examples/system/console/main/cmd_wifi.c index c60f1e81b..8233203d2 100644 --- a/examples/system/console/main/cmd_wifi.c +++ b/examples/system/console/main/cmd_wifi.c @@ -36,7 +36,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGI(__func__, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/system/factory-test/components/rf_test/lib/librftest.a b/examples/system/factory-test/components/rf_test/lib/librftest.a index 63d15ca7b..d76a39ea6 100755 Binary files a/examples/system/factory-test/components/rf_test/lib/librftest.a and b/examples/system/factory-test/components/rf_test/lib/librftest.a differ diff --git a/examples/system/ota/native_ota/1MB_flash/new_to_new_no_old/main/ota_example_main.c b/examples/system/ota/native_ota/1MB_flash/new_to_new_no_old/main/ota_example_main.c index 4f1838da2..7e6c29bab 100644 --- a/examples/system/ota/native_ota/1MB_flash/new_to_new_no_old/main/ota_example_main.c +++ b/examples/system/ota/native_ota/1MB_flash/new_to_new_no_old/main/ota_example_main.c @@ -92,7 +92,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/system/ota/native_ota/1MB_flash/new_to_new_no_old_copy/main/ota_example_main.c b/examples/system/ota/native_ota/1MB_flash/new_to_new_no_old_copy/main/ota_example_main.c index 4df5a4944..d7cd125aa 100644 --- a/examples/system/ota/native_ota/1MB_flash/new_to_new_no_old_copy/main/ota_example_main.c +++ b/examples/system/ota/native_ota/1MB_flash/new_to_new_no_old_copy/main/ota_example_main.c @@ -92,7 +92,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/system/ota/native_ota/1MB_flash/new_to_new_with_old/main/ota_example_main.c b/examples/system/ota/native_ota/1MB_flash/new_to_new_with_old/main/ota_example_main.c index 53bb569c8..29bdf0a7c 100644 --- a/examples/system/ota/native_ota/1MB_flash/new_to_new_with_old/main/ota_example_main.c +++ b/examples/system/ota/native_ota/1MB_flash/new_to_new_with_old/main/ota_example_main.c @@ -95,7 +95,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/system/ota/native_ota/2+MB_flash/new_to_new_no_old/main/ota_example_main.c b/examples/system/ota/native_ota/2+MB_flash/new_to_new_no_old/main/ota_example_main.c index 4df5a4944..d7cd125aa 100644 --- a/examples/system/ota/native_ota/2+MB_flash/new_to_new_no_old/main/ota_example_main.c +++ b/examples/system/ota/native_ota/2+MB_flash/new_to_new_no_old/main/ota_example_main.c @@ -92,7 +92,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/system/ota/native_ota/2+MB_flash/new_to_new_with_old/main/ota_example_main.c b/examples/system/ota/native_ota/2+MB_flash/new_to_new_with_old/main/ota_example_main.c index 53bb569c8..29bdf0a7c 100644 --- a/examples/system/ota/native_ota/2+MB_flash/new_to_new_with_old/main/ota_example_main.c +++ b/examples/system/ota/native_ota/2+MB_flash/new_to_new_with_old/main/ota_example_main.c @@ -95,7 +95,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/system/ota/simple_ota_example/main/simple_ota_example.c b/examples/system/ota/simple_ota_example/main/simple_ota_example.c index c2796429d..717dca85c 100644 --- a/examples/system/ota/simple_ota_example/main/simple_ota_example.c +++ b/examples/system/ota/simple_ota_example/main/simple_ota_example.c @@ -77,7 +77,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/wifi/power_save/README.md b/examples/wifi/power_save/README.md index c955ac064..888cc6ae3 100644 --- a/examples/wifi/power_save/README.md +++ b/examples/wifi/power_save/README.md @@ -2,12 +2,12 @@ This example shows how to use power save mode of wifi. -Power save mode only works in station mode. If the modem sleep mode is enabled, station will switch between active and sleep state periodically after connecting to AP successfully. Station can keep connection with AP in modem sleep mode. +Power save mode only works in station mode. If the modem sleep mode is enabled, station will switch between active and sleep state periodically after connecting to AP successfully. In sleep state, RF, PHY and BB are turned off in order to reduce power consumption. Station can keep connection with AP in modem sleep mode. * No power save: This is default mode. And the esp8266 will work with full power. -* Minimum modem sleep: In minimum modem sleep mode, station wakes up every DTIM to receive beacon. In sleep state, RF, PHY and BB are turned off in order to reduce power consumption. . +* Minimum modem sleep: In minimum modem sleep mode, station wakes up every DTIM to receive beacon. Broadcast data will not be lost because it is transmitted after DTIM. However, it can not save much more power if DTIM is short for DTIM is determined by AP. -* Maximum modem sleep: In maximum modem sleep mode, station wakes up every DTIM to receive beacon. In sleep state, CPU, RF, PHY and BB are turned off in order to reduce power consumption. . +* Maximum modem sleep: In maximum modem sleep mode, station wakes up every listen interval to receive beacon. Broadcast data may be lost because station may be in sleep state at DTIM time. If listen interval is longer, more power is saved but broadcast data is more easy to lose. * others: not supported yet. diff --git a/examples/wifi/power_save/main/power_save.c b/examples/wifi/power_save/main/power_save.c index 83872e751..9b119fa05 100644 --- a/examples/wifi/power_save/main/power_save.c +++ b/examples/wifi/power_save/main/power_save.c @@ -10,7 +10,7 @@ /* this example shows how to use power save mode set a router or a AP using the same SSID&PASSWORD as configuration of this example. - start esp32 and when it connected to AP it will enter power save mode + start esp8266 and when it connected to AP it will enter power save mode */ #include #include "freertos/FreeRTOS.h" @@ -18,6 +18,7 @@ #include "freertos/event_groups.h" #include "rom/ets_sys.h" #include "esp_wifi.h" +#include "esp_sleep.h" #include "esp_event_loop.h" #include "esp_log.h" #include "nvs_flash.h" @@ -68,7 +69,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); break; @@ -104,6 +105,13 @@ static void wifi_power_save(void) EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); ESP_LOGI(TAG, "esp_wifi_set_ps()."); esp_wifi_set_ps(DEFAULT_PS_MODE); + +#if CONFIG_PM_ENABLE + esp_pm_config_esp8266_t pm_config = { + .light_sleep_enable = true + }; + ESP_ERROR_CHECK( esp_pm_configure(&pm_config) ); +#endif // CONFIG_PM_ENABLE } void app_main(void) diff --git a/examples/wifi/simple_wifi/main/simple_wifi.c b/examples/wifi/simple_wifi/main/simple_wifi.c index 975d393e0..47f3c9f97 100644 --- a/examples/wifi/simple_wifi/main/simple_wifi.c +++ b/examples/wifi/simple_wifi/main/simple_wifi.c @@ -65,11 +65,15 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT); break; + case SYSTEM_EVENT_AP_STAIPASSIGNED: + ESP_LOGI(TAG, "assigned ip:%s", + ip4addr_ntoa(&event->event_info.ap_staipassigned.ip)); + break; default: break; } @@ -122,6 +126,14 @@ void wifi_init_sta() }, }; + /* Setting a password implies station will connect to all security modes including WEP/WPA. + * However these modes are deprecated and not advisable to be used. Incase your Access point + * doesn't support WPA2, these mode can be enabled by commenting below line */ + + if (strlen(EXAMPLE_ESP_WIFI_PASS)) { + wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; + } + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); ESP_ERROR_CHECK(esp_wifi_start() ); diff --git a/examples/wifi/smart_config/main/smartconfig_main.c b/examples/wifi/smart_config/main/smartconfig_main.c index 5bca3459c..5ca2c3f2c 100644 --- a/examples/wifi/smart_config/main/smartconfig_main.c +++ b/examples/wifi/smart_config/main/smartconfig_main.c @@ -49,7 +49,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); diff --git a/examples/wifi/wpa2_enterprise/main/wpa2_enterprise_main.c b/examples/wifi/wpa2_enterprise/main/wpa2_enterprise_main.c index c24466cd1..0a263edf3 100644 --- a/examples/wifi/wpa2_enterprise/main/wpa2_enterprise_main.c +++ b/examples/wifi/wpa2_enterprise/main/wpa2_enterprise_main.c @@ -110,7 +110,7 @@ static esp_err_t event_handler(void* ctx, system_event_t* event) if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } esp_wifi_connect(); diff --git a/examples/wifi/wps/main/wps.c b/examples/wifi/wps/main/wps.c index bef9ebb8b..f3de273c8 100644 --- a/examples/wifi/wps/main/wps.c +++ b/examples/wifi/wps/main/wps.c @@ -60,7 +60,7 @@ static esp_err_t event_handler(void* ctx, system_event_t* event) ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason); if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) { /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N); + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); } ESP_ERROR_CHECK(esp_wifi_connect()); break; diff --git a/export.sh b/export.sh new file mode 100755 index 000000000..38a0b828e --- /dev/null +++ b/export.sh @@ -0,0 +1,100 @@ +# This script should be sourced, not executed. + +function realpath_int() { + wdir="$PWD"; [ "$PWD" = "/" ] && wdir="" + arg=$1 + case "$arg" in + /*) scriptdir="${arg}";; + *) scriptdir="$wdir/${arg#./}";; + esac + scriptdir="${scriptdir%/*}" + echo "$scriptdir" +} + + +function idf_export_main() { + # The file doesn't have executable permissions, so this shouldn't really happen. + # Doing this in case someone tries to chmod +x it and execute... + if [[ -n "${BASH_SOURCE}" && ( "${BASH_SOURCE[0]}" == "${0}" ) ]]; then + echo "This script should be sourced, not executed:" + echo ". ${BASH_SOURCE[0]}" + return 1 + fi + + if [[ -z "${IDF_PATH}" ]] + then + # If using bash, try to guess IDF_PATH from script location + if [[ -n "${BASH_SOURCE}" ]] + then + if [[ "$OSTYPE" == "darwin"* ]]; then + script_dir="$(realpath_int $BASH_SOURCE)" + else + script_name="$(readlink -f $BASH_SOURCE)" + script_dir="$(dirname $script_name)" + fi + export IDF_PATH="${script_dir}" + else + echo "IDF_PATH must be set before sourcing this script" + return 1 + fi + fi + + old_path=$PATH + + echo "Adding ESP-IDF tools to PATH..." + # Call idf_tools.py to export tool paths + export IDF_TOOLS_EXPORT_CMD=${IDF_PATH}/export.sh + export IDF_TOOLS_INSTALL_CMD=${IDF_PATH}/install.sh + idf_exports=$(${IDF_PATH}/tools/idf_tools.py export) || return 1 + eval "${idf_exports}" + + echo "Checking if Python packages are up to date..." + python ${IDF_PATH}/tools/check_python_dependencies.py || return 1 + + + # Allow calling some IDF python tools without specifying the full path + # ${IDF_PATH}/tools is already added by 'idf_tools.py export' + IDF_ADD_PATHS_EXTRAS="${IDF_PATH}/components/esptool_py/esptool" + IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/components/partition_table/" + export PATH="${IDF_ADD_PATHS_EXTRAS}:${PATH}" + + if [[ -n "$BASH" ]] + then + path_prefix=${PATH%%${old_path}} + paths="${path_prefix//:/ }" + if [ -n "${paths}" ]; then + echo "Added the following directories to PATH:" + else + echo "All paths are already set." + fi + for path_entry in ${paths} + do + echo " ${path_entry}" + done + else + echo "Updated PATH variable:" + echo " ${PATH}" + fi + + # Clean up + unset old_path + unset paths + unset path_prefix + unset path_entry + unset IDF_ADD_PATHS_EXTRAS + unset idf_exports + + # Not unsetting IDF_PYTHON_ENV_PATH, it can be used by IDF build system + # to check whether we are using a private Python environment + + echo "Done! You can now compile ESP8266-RTOS-SDK projects." + echo "Go to the project directory and run:" + echo "" + echo " make" + echo "" +} + +idf_export_main + +unset realpath_int +unset idf_export_main diff --git a/install.sh b/install.sh new file mode 100755 index 000000000..d026e3c93 --- /dev/null +++ b/install.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +set -e +set -u + +export IDF_PATH=$(cd $(dirname $0); pwd) + +echo "Installing ESP-IDF tools" +${IDF_PATH}/tools/idf_tools.py install + +echo "Installing Python environment and packages" +${IDF_PATH}/tools/idf_tools.py install-python-env + +basedir="$(dirname $0)" +echo "All done! You can now run:" +echo "" +echo " . ${basedir}/export.sh" +echo "" diff --git a/requirements.txt b/requirements.txt index a43c6d4ae..6a9793304 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,6 +8,6 @@ setuptools click>=5.0 pyserial>=3.0 future>=0.15.2 -cryptography>=2.1.4 +cryptography>=2.1.4,<35 pyparsing>=2.0.3,<2.4.0 pyelftools>=0.22 diff --git a/tools/idf_tools.py b/tools/idf_tools.py index 7cdd18236..21c8f6907 100755 --- a/tools/idf_tools.py +++ b/tools/idf_tools.py @@ -800,7 +800,7 @@ def get_python_env_path(): idf_version = match.group(1) idf_python_env_path = os.path.join(global_idf_tools_path, 'python_env', - 'idf{}_py{}_env'.format(idf_version, python_ver_major_minor)) + 'rtos{}_py{}_env'.format(idf_version, python_ver_major_minor)) if sys.platform == 'win32': subdir = 'Scripts' @@ -1066,7 +1066,7 @@ def action_install_python_env(args): subprocess.check_call([sys.executable, '-m', 'pip', 'install', '--user', 'virtualenv'], stdout=sys.stdout, stderr=sys.stderr) - subprocess.check_call([sys.executable, '-m', 'virtualenv', '--no-site-packages', idf_python_env_path], + subprocess.check_call([sys.executable, '-m', 'virtualenv', idf_python_env_path], stdout=sys.stdout, stderr=sys.stderr) run_args = [virtualenv_python, '-m', 'pip', 'install', '--no-warn-script-location'] requirements_txt = os.path.join(global_idf_path, 'requirements.txt') diff --git a/tools/tools.json b/tools/tools.json index 5bbed7e8b..aa4cabf30 100644 --- a/tools/tools.json +++ b/tools/tools.json @@ -1,10 +1,10 @@ { "tools": [ { - "description": "Toolchain for Xtensa (ESP32) based on GCC", + "description": "Toolchain for Xtensa (ESP8266) based on GCC", "export_paths": [ [ - "xtensa-esp32-elf", + "xtensa-lx106-elf", "bin" ] ], @@ -12,9 +12,9 @@ "info_url": "https://github.com/espressif/crosstool-NG", "install": "always", "license": "GPL-3.0-with-GCC-exception", - "name": "xtensa-esp32-elf", + "name": "xtensa-lx106-elf", "version_cmd": [ - "xtensa-esp32-elf-gcc", + "xtensa-lx106-elf-gcc", "--version" ], "version_regex": "\\(crosstool-NG\\s+(?:crosstool-ng-)?([0-9a-z\\.\\-]+)\\)\\s*([0-9\\.]+)", @@ -22,81 +22,31 @@ "versions": [ { "linux-amd64": { - "sha256": "39db59b13f25e83e53c55f56979dbfce77b7f23126ad79de833509ad902d3f0a", - "size": 63025996, - "url": "https://dl.espressif.com/dl/xtensa-esp32-elf-gcc8_2_0-esp32-2019r1-linux-amd64.tar.gz" - }, - "linux-armel": { - "sha256": "4ffd19839fcb241af3111da7c419448b80be3bd844da570e95f8f3d5a7eccf79", - "size": 61164309, - "url": "https://dl.espressif.com/dl/xtensa-esp32-elf-gcc8_2_0-esp32-2019r1-linux-armel.tar.gz" + "sha256": "706a02853759c2f85d912f68df4f5b4566ecb41422de5afe35a45d064eb8e494", + "size": 37049855, + "url": "https://dl.espressif.com/dl/xtensa-lx106-elf-linux64-1.22.0-100-ge567ec7-5.2.0.tar.gz" }, "linux-i686": { - "sha256": "85c02a4310bb97ac46e6f943b0de10e9e9572596c7d33d09b6f93f8bace3b784", - "size": 65016647, - "url": "https://dl.espressif.com/dl/xtensa-esp32-elf-gcc8_2_0-esp32-2019r1-linux-i686.tar.gz" - }, - "macos": { - "sha256": "adb256394c948ca424ec6ef1d9bee91baa99a304d8ace8e6701303da952eb007", - "size": 69674700, - "url": "https://dl.espressif.com/dl/xtensa-esp32-elf-gcc8_2_0-esp32-2019r1-macos.tar.gz" - }, - "name": "esp32-2019r1-8.2.0", - "status": "recommended", - "win32": { - "sha256": "ff00dbb02287219a61873c3b2649a50b94e80c82e607c336383f2838abbefbde", - "size": 73245169, - "url": "https://dl.espressif.com/dl/xtensa-esp32-elf-gcc8_2_0-esp32-2019r1-win32.zip" - }, - "win64": { - "sha256": "ff00dbb02287219a61873c3b2649a50b94e80c82e607c336383f2838abbefbde", - "size": 73245169, - "url": "https://dl.espressif.com/dl/xtensa-esp32-elf-gcc8_2_0-esp32-2019r1-win32.zip" - } - } - ] - }, - { - "description": "Toolchain for ESP32 ULP coprocessor", - "export_paths": [ - [ - "esp32ulp-elf-binutils", - "bin" - ] - ], - "export_vars": {}, - "info_url": "https://github.com/espressif/binutils-esp32ulp", - "install": "always", - "license": "GPL-2.0-or-later", - "name": "esp32ulp-elf", - "version_cmd": [ - "esp32ulp-elf-as", - "--version" - ], - "version_regex": "\\(GNU Binutils\\)\\s+([0-9a-z\\.\\-]+)", - "versions": [ - { - "linux-amd64": { - "sha256": "c1bbcd65e1e30c7312a50344c8dbc70c2941580a79aa8f8abbce8e0e90c79566", - "size": 8246604, - "url": "https://dl.espressif.com/dl/binutils-esp32ulp-linux64-2.28.51-esp32ulp-20180809.tar.gz" + "sha256": "a94df9788a73a362f01f32a6f9d46b8630a0aab708eec8d6523e72342f382769", + "size": 38388423, + "url": "https://dl.espressif.com/dl/xtensa-lx106-elf-linux32-1.22.0-100-ge567ec7-5.2.0.tar.gz" }, "macos": { - "sha256": "c92937d85cc9a90eb6c6099ce767ca021108c18c94e34bd7b1fa0cde168f94a0", - "size": 5726662, - "url": "https://dl.espressif.com/dl/binutils-esp32ulp-macos-2.28.51-esp32ulp-20180809.tar.gz" + "sha256": "4e3b2e6ba8ab7ff4dc4b70d90a181763b2077e4b6a69106241f8c175bab18184", + "size": 43153405, + "url": "https://dl.espressif.com/dl/xtensa-lx106-elf-macos-1.22.0-100-ge567ec7-5.2.0.tar.gz" }, - "name": "2.28.51.20170517", + "name": "1.22.0-100-ge567ec7-5.2.0", "status": "recommended", "win32": { - "sha256": "92dc83e69e534c9f73d7b939088f2e84f757d2478483415d17fe9dd1c236f2fd", - "size": 12231559, - "url": "https://dl.espressif.com/dl/binutils-esp32ulp-win32-2.28.51-esp32ulp-20180809.zip" + "sha256": "0756bb6e768fb986ec557bf1136a8978e106d7d2cca1bbb21fca5d566a30e468", + "size": 39567257, + "url": "https://dl.espressif.com/dl/xtensa-lx106-elf-win32-1.22.0-100-ge567ec7-5.2.0.zip" }, "win64": { - "sha256": "92dc83e69e534c9f73d7b939088f2e84f757d2478483415d17fe9dd1c236f2fd", - "size": 12231559, - "url": "https://dl.espressif.com/dl/binutils-esp32ulp-win32-2.28.51-esp32ulp-20180809.zip" + "sha256": "0756bb6e768fb986ec557bf1136a8978e106d7d2cca1bbb21fca5d566a30e468", + "size": 39567257, + "url": "https://dl.espressif.com/dl/xtensa-lx106-elf-win32-1.22.0-100-ge567ec7-5.2.0.zip" } } ] @@ -167,53 +117,6 @@ } ] }, - { - "description": "OpenOCD for ESP32", - "export_paths": [ - [ - "openocd-esp32", - "bin" - ] - ], - "export_vars": { - "OPENOCD_SCRIPTS": "${TOOL_PATH}/openocd-esp32/share/openocd/scripts" - }, - "info_url": "https://github.com/espressif/openocd-esp32", - "install": "always", - "license": "GPL-2.0-only", - "name": "openocd-esp32", - "version_cmd": [ - "openocd", - "--version" - ], - "version_regex": "Open On-Chip Debugger\\s+([a-z0-9.-]+)\\s+", - "versions": [ - { - "linux-amd64": { - "sha256": "e5b5579edffde090e426b4995b346e281843bf84394f8e68c8e41bd1e4c576bd", - "size": 1681596, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20190313/openocd-esp32-linux64-0.10.0-esp32-20190313.tar.gz" - }, - "macos": { - "sha256": "09504eea5aa92646a117f16573c95b34e04b4010791a2f8fefcd2bd8c430f081", - "size": 1760536, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20190313/openocd-esp32-macos-0.10.0-esp32-20190313.tar.gz" - }, - "name": "v0.10.0-esp32-20190313", - "status": "recommended", - "win32": { - "sha256": "b86a7f9f39dfc4d8e289fc819375bbb7a5e9fcb8895805ba2b5faf67b8b25ce2", - "size": 2098513, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20190313/openocd-esp32-win32-0.10.0-esp32-20190313.zip" - }, - "win64": { - "sha256": "b86a7f9f39dfc4d8e289fc819375bbb7a5e9fcb8895805ba2b5faf67b8b25ce2", - "size": 2098513, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20190313/openocd-esp32-win32-0.10.0-esp32-20190313.zip" - } - } - ] - }, { "description": "menuconfig tool", "export_paths": [