From 058cf73a35e8d3f219ad3aa96517f71450d2bebd Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 10 Dec 2019 10:46:04 +0800 Subject: [PATCH 01/89] fix(lib): fix probe request length error --- components/esp8266/lib/VERSION | 2 +- components/esp8266/lib/libpp.a | Bin 264416 -> 264476 bytes components/esp8266/lib/libpp_dbg.a | Bin 284724 -> 284848 bytes 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index f3c64ab41..b7b8425fa 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -1,7 +1,7 @@ gwen: core: 27927af net80211: b7de510 - pp: b7de510 + pp: b01a3a6 wpa: 27927af espnow: 27927af wps: 27927af diff --git a/components/esp8266/lib/libpp.a b/components/esp8266/lib/libpp.a index 3d3ef4edc917771b827eba7ef92ca824c5450874..3651cb87ea99270240fa9c45a42fbe77dc96f563 100644 GIT binary patch delta 6822 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 delta 6800 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 diff --git a/components/esp8266/lib/libpp_dbg.a b/components/esp8266/lib/libpp_dbg.a index 196a265ca1c63a5a9b364e9d119b7ae80349bca6..8bf8759d554c236958ffe7a93875d8e074026c57 100644 GIT binary patch delta 11809 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 MQ`$GqbQtP?0o0KOXaE2J From 7a5685f3ee50fc1aab16f17bd3394e26543e1240 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 10 Dec 2019 14:26:22 +0800 Subject: [PATCH 02/89] feat(esp-tls): modify esp-tls structure members' offset of platform dependece --- components/esp-tls/esp_tls.h | 44 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/components/esp-tls/esp_tls.h b/components/esp-tls/esp_tls.h index bd93764e6..7e9e0b516 100644 --- a/components/esp-tls/esp_tls.h +++ b/components/esp-tls/esp_tls.h @@ -249,6 +249,28 @@ typedef struct esp_tls_cfg_server { * @brief ESP-TLS Connection Handle */ typedef struct esp_tls { + 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. */ + + esp_tls_conn_state_t conn_state; /*!< ESP-TLS Connection state */ + + fd_set rset; /*!< read file descriptors */ + + fd_set wset; /*!< write file descriptors */ + + bool is_tls; /*!< indicates connection type (TLS or NON-TLS) */ + + esp_tls_role_t role; /*!< esp-tls role + - ESP_TLS_CLIENT + - ESP_TLS_SERVER */ + + esp_tls_error_handle_t error_handle; /*!< handle to error descriptor */ + #ifdef CONFIG_ESP_TLS_USING_MBEDTLS mbedtls_ssl_context ssl; /*!< TLS/SSL context */ @@ -282,28 +304,6 @@ typedef struct esp_tls { void *priv_ctx; 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. */ - - esp_tls_conn_state_t conn_state; /*!< ESP-TLS Connection state */ - - fd_set rset; /*!< read file descriptors */ - - fd_set wset; /*!< write file descriptors */ - - bool is_tls; /*!< indicates connection type (TLS or NON-TLS) */ - - esp_tls_role_t role; /*!< esp-tls role - - ESP_TLS_CLIENT - - ESP_TLS_SERVER */ - - esp_tls_error_handle_t error_handle; /*!< handle to error descriptor */ - } esp_tls_t; From 16c2dedac90d50c29abce80ea216ff5c8c11f4bc Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Wed, 11 Dec 2019 14:08:15 +0800 Subject: [PATCH 03/89] chore(mqtt): modify default mqtt IBM MQTT will be removed at v3.4. --- components/mqtt/Kconfig | 4 ++-- examples/protocols/ibm-mqtt/sdkconfig.defaults | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) 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/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= From 46ba9ae7380b6e52550c6f3d4b22b4ebd604a916 Mon Sep 17 00:00:00 2001 From: Zhang Jun Hao Date: Fri, 13 Dec 2019 19:27:03 +0800 Subject: [PATCH 04/89] feat(lib): add more info when softap deny station --- components/esp8266/lib/VERSION | 2 +- components/esp8266/lib/libnet80211.a | Bin 392048 -> 392516 bytes components/esp8266/lib/libnet80211_dbg.a | Bin 431900 -> 431908 bytes 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index b7b8425fa..4e8fedcd6 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -1,6 +1,6 @@ gwen: core: 27927af - net80211: b7de510 + net80211: a2ac2bd pp: b01a3a6 wpa: 27927af espnow: 27927af diff --git a/components/esp8266/lib/libnet80211.a b/components/esp8266/lib/libnet80211.a index be5bcbbee27d06fc626b81790f29e36462b05e00..24021b7e3f605731305d3e657ebcb1ee6acb5b20 100644 GIT binary patch delta 3570 zcmZXW4Nz3q702&=`yOC-k%e7d6ew?3{6euTXvD7w(Y7XI6j7tLqOLB9%phOl6de_4 zt4=c{F`?FYecjmtP zKfm`s_nvp(d;7NcuIIfW&)&57hw}3C^QRZI`6iCFbjyReBj4OO_PNm(c=N&B8CkL5 z;oz!HD+nE&EKg-y5$(*-J)xQv^4jnidVQOg8mfI#W(D%_mqt931vc+s+irKv>!nx*xXf%&<@hGw(>UqUfHE%F(Cnvrq^dxIY++P;Ro#ium4z(sPVo z`7A=bs6I7+dLFe^$?=+dUnr&6khbZY0`=yGs>;f;4Rz&Jm0nR+TWba?YRdw_t!7~J z=Bf?lWkIh9ln1{*Hdt!bRaKc4f!e3asIA0s(b%PiCvD5-vRX4(WmZ<546Sd9YLVR)ZX*yGBq{?0Naiw9>$J^vidg+$U`O2OuL(<%8BZ0bR z=sKO*s3lPADyfHFsx}6bXzg~x(eP~{gogeuI=2LL)-%zW-$Uo8gZUu33*CoqXNbm} z^#qK}^PxG9`84Q#7&*T16+i3ZD9;xeIO{>c$y3>h#>uRwVr0G%+O70_ z`9pRH@v`zTV{KRbRmD$ZT#0km1)Nlz8EfkT+7-v!*&tSPLK6;Xe^Muyv9^j>huFFW zx0Qz(YwH#S+0%#vnx;i}lo@M#BU3QN`2kFeXxx8({Ws#IJRk9hah3@oYrEnV?D=if zGhKO@v9>E-&7Sw8p6@6RGuC#+7c0(1)a7tOXEb50I#Gv^wO#Qt#WOTI_-~m>AIvkd zS{_|BJ>+8rhzYh1Q*@{KJo;WFz${M;1!-UA8C7IGixxK(wsi+tDh@DIFpVHk(MB z{4O#v*CgWv_j5UKW}~|o#ea)DMEBa@_IS1 zljH#M9Qc~9jnKjY&@NiSv;y=8boeyx>Hk#WsHT?(Fx%&Flt=Qqk*6J~rhdl7ZXr_0 z{|A&2|Ml{lYv_?Xa0KC)7D;TpgT&SvdV%qNV7c$iVg!At(o{{MmH}?`#`nU%$8>#9!a@F$o(f3 z4Z%3Z6vCvYNqD{+fwhWV^uiD-ndik{A@WWJ?*dOu--8%W&Tc&FKWYigO*3ZY;hRAh f-_yq=HqH{F)q%$YCrew}a58rRzEb2pr@Q_GjQJy0 delta 3052 zcmY+G4^ULs6~^y<`|gU}1r~O7L04H<6rtb%kq%f%Fp}8JfC8e?j1XYZNgE8_{9lV;yZ9M`CoH#e(UpKO$Q--x2>8E_dd z%2%gF5i0w`Cw9w!t0=O{cfBl+?YB`F3;$FSjTYA#=|(iFt~Z{T8I91$iK=K+-T!sx zPd+iK0@2)Hx_V&H(755X5n26(CX6|yQDik!wbHR~@BbtDzQY-7qj20Oj-3CMLF5lt z-E!yji_@Ir#xPZT?k49)W!C^;y@4|sB_3MyL zh&MGKD#%_!U5zr$DEfIgu}nz^y+Ms1S(B62~9zTDnCEXf&&R0LvkKQcnzX{C-Q zD~!jp#kyngpRBes8ARm@MXoyGn_4SL!D;jOcN-Ul~I8$>ahX(lP9eL z^Ad8gM^;9u%B_ekjK_i#%t0PK;>tQO#d^n5jE4RFc%|7NN`nd1%U3!0m>d z@}Lzq6m(Y9Wfc?}74Fo~Lg%A>3uFiFZd5_~=X6JFIHgH>q+Czs&loA;)mzn2JUzQz zxsx-{oq?lO&oP*Pj3bTWZW#WSWXKSX9vnP4&H4Zi=1)l>Y|js%xfFZ0L6>Py542zF zPoa6RhxHQ7T*rfjKCM%^2nIYIzs(4R7qzO+8P4?}eKP!KQWNpNuk!BvWP31Gh^-2yo5b`Lou#v4>Q&-&C3wWKe9uJLG1xsX$3Bw zxT_P~L?w*!vgH@k5c6$f#@eNMtmZwE4&Rq4;U8U7HHp@X1ICX%DDcgx0t2iwJIb3D zQ+AzPMCVVLWprfNC<~9=RQ<}RSxr|4)heTZHO>7}t&%?4@}*iWO?nTL@k%+x4XF$n zLsy?Nyi_uzJgUSY#M+MA`CfV+q0wGJ`-ap)d6eE7QfbD_gRGKlY(o~ttu3tHf_hTk)0+q*UKPKa79i1Ik3srus z5KWY`&G6Cau!=X%ZzAU%@Z;bctmcaEpt+{avHQ%vz_$4Oeay(sO8l+K#%ETr5 zwzX!-2-ci>mL4BLsUqNwl<>CcqrD?4UKY`T5x6^nU$ERCv-?~F{fpf`{0gtPaOxGbn zoZu;i&cfmbAA@Z!Em3PtRWD{)$mXFc? zyC`0QtVvyuIlR<|v@E927?fEpt&(9V0<;RF1} zyk_lip7AR$(G|uuv+#tocF{V_aUpwBvbQc+(NvJWECa!8v%2r5dWZgJ*M}+yLrWu diff --git a/components/esp8266/lib/libnet80211_dbg.a b/components/esp8266/lib/libnet80211_dbg.a index 8049f519dcd573ffb6468277d6794da460fff3a0..da8afc7a446c00d3e1c21b588324d06c3ed72c27 100644 GIT binary patch delta 3651 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 From b29087fd5c02a0a20ebfa371d51299b42b7abcc3 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 10 Dec 2019 14:23:00 +0800 Subject: [PATCH 05/89] feat(util): refactor SHA algorithm of util components --- .../bootloader_support/src/bootloader_sha.c | 8 +- components/libsodium/Kconfig | 2 +- .../mbedtls/port/esp8266/include/sha256_alt.h | 2 +- components/util/Kconfig | 2 +- components/util/include/esp_sha.h | 174 +---- components/util/src/sha.c | 599 ------------------ components/util/src/sha1.c | 165 +++++ components/util/src/sha256.c | 239 +++++++ components/util/src/sha512.c | 297 +++++++++ .../wpa_supplicant/include/crypto/sha1_i.h | 2 +- .../src/crypto/sha256-internal.c | 4 +- 11 files changed, 741 insertions(+), 753 deletions(-) delete mode 100644 components/util/src/sha.c create mode 100644 components/util/src/sha1.c create mode 100644 components/util/src/sha256.c create mode 100644 components/util/src/sha512.c 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/libsodium/Kconfig b/components/libsodium/Kconfig index a63a86c18..58b33bdfb 100644 --- a/components/libsodium/Kconfig +++ b/components/libsodium/Kconfig @@ -3,7 +3,7 @@ menu "libsodium" config LIBSODIUM_USE_MBEDTLS_SHA bool "Use mbedTLS SHA256 & SHA512 implementations" default y - depends on !ESP_SHA + depends on !MBEDTLS_HARDWARE_SHA help If this option is enabled, libsodium will use thin wrappers around mbedTLS for SHA256 & SHA512 operations. 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/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..d929ead83 100644 --- a/components/util/include/esp_sha.h +++ b/components/util/include/esp_sha.h @@ -21,63 +21,28 @@ extern "C" { #endif -typedef int (*sha_cal_t)(void *ctx, const void *src); - -typedef enum { - SHA1 = 0, - SHA224 = 1, - SHA256 = 2, - SHA384 = 3, - SHA512 = 4, - - SHA_INVALID = -1, -} esp_sha_type_t; +typedef struct { + uint32_t state[5]; + uint32_t total[2]; + uint8_t buffer[64]; +} esp_sha1_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 length; + uint32_t curlen; + uint32_t state[8]; + uint8_t buf[64]; +} esp_sha256_t; 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. */ + uint64_t total[2]; + uint64_t state[8]; + uint8_t buffer[128]; } 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 +51,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 +60,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 +69,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 +78,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 +87,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 +98,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 +109,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 +120,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 +131,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 +142,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 +152,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 +162,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 +172,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 +182,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 +192,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..bc585dad8 --- /dev/null +++ b/components/util/src/sha256.c @@ -0,0 +1,239 @@ +// 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, 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->curlen = 0; + ctx->length = 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->curlen = 0; + ctx->length = 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) +{ + const uint8_t *in = (const uint8_t *)src; + uint32_t n; + + util_assert(ctx); + util_assert(src); + util_assert(size); + + if (ctx->curlen >= sizeof(ctx->buf)) + return -1; + + while (size > 0) { + if (ctx->curlen == 0 && size >= 64) { + esp_sha256_transform(ctx, (uint8_t *) in); + + ctx->length += 64 * 8; + in += 64; + size -= 64; + } else { + n = MIN(size, (64 - ctx->curlen)); + memcpy(ctx->buf + ctx->curlen, in, n); + ctx->curlen += n; + in += n; + size -= n; + + if (ctx->curlen == 64) { + esp_sha256_transform(ctx, ctx->buf); + + ctx->length += 8 * 64; + ctx->curlen = 0; + } + } + } + + 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) +{ + int i; + uint8_t *out = (uint8_t *)dest; + + util_assert(ctx); + util_assert(dest); + + if (ctx->curlen >= sizeof(ctx->buf)) + return -1; + + ctx->length += ctx->curlen * 8; + + ctx->buf[ctx->curlen++] = 0x80; + + if (ctx->curlen > 56) { + while (ctx->curlen < 64) + ctx->buf[ctx->curlen++] = 0; + + esp_sha256_transform(ctx, ctx->buf); + ctx->curlen = 0; + } + + while (ctx->curlen < 56) + ctx->buf[ctx->curlen++] = 0; + + ESP_PUT_BE64(ctx->buf + 56, ctx->length); + esp_sha256_transform(ctx, ctx->buf); + + for (i = 0; i < 7; i++) + ESP_PUT_BE32(out + (4 * i), ctx->state[i]); + + return 0; +} + +int esp_sha256_finish(esp_sha256_t *ctx, void *dest) +{ + uint8_t *out = (uint8_t *)dest; + + util_assert(ctx); + util_assert(dest); + + esp_sha224_finish(ctx, dest); + + ESP_PUT_BE32(out + 28, ctx->state[7]); + + return 0; +} diff --git a/components/util/src/sha512.c b/components/util/src/sha512.c new file mode 100644 index 000000000..92230a27c --- /dev/null +++ b/components/util/src/sha512.c @@ -0,0 +1,297 @@ +// 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->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->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; + + memset(ctx->buffer + used, 0, 112 - used); + + if (used > 112) { + 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); + + return 0; +} + +int esp_sha512_finish(esp_sha512_t *ctx, void *dest) +{ + uint8_t *output = (uint8_t *)dest; + + util_assert(ctx); + util_assert(dest); + + esp_sha384_finish(ctx, dest); + + PUT_UINT64_BE(ctx->state[6], output, 48); + PUT_UINT64_BE(ctx->state[7], output, 56); + + 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 From 1a51815633db16b4ccbb7c36b04b6200fec04768 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 16 Dec 2019 19:36:36 +0800 Subject: [PATCH 06/89] feat(esp8266): fix CPU light sleep process --- components/esp8266/include/driver/rtc.h | 5 ++ components/esp8266/source/esp_sleep.c | 108 ++++++++++++++++++------ 2 files changed, 89 insertions(+), 24 deletions(-) diff --git a/components/esp8266/include/driver/rtc.h b/components/esp8266/include/driver/rtc.h index 7715014c1..913be713f 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 */ diff --git a/components/esp8266/source/esp_sleep.c b/components/esp8266/source/esp_sleep.c index 10231283a..dd0068a93 100644 --- a/components/esp8266/source/esp_sleep.c +++ b/components/esp8266/source/esp_sleep.c @@ -21,7 +21,9 @@ #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 +39,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 (3072) #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,6 +54,11 @@ 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; static uint16_t s_lock_cnt = 1; @@ -76,6 +84,8 @@ static inline void restore_local_wdev(uint32_t reg) 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 +106,50 @@ 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 uint32_t sleep_rtc_ticks(pm_soc_clk_t *clk) +{ + uint32_t rtc_ticks; + + clk->cal_period = pm_rtc_clock_cali_proc(); + + rtc_ticks = pm_usec2rtc(clk->sleep_us - SLEEP_PROC_TIME, clk->cal_period); + + return rtc_ticks; } -static inline void update_soc_clk(pm_soc_clk_t *clk, uint32_t us) +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, total_rtc, 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 = pm_rtc2usec(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; + + 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 +158,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,6 +170,32 @@ static int cpu_is_wait_mode(void) return (s_sleep_mode == ESP_CPU_WAIT) || s_lock_cnt; } +static int cpu_reject_sleep(void) +{ + 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; + } + } + } + } + + return ret; +} + void esp_wifi_hw_open(void) { phy_open_rf(); @@ -209,13 +271,13 @@ esp_err_t esp_light_sleep_start(void) 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); + const uint32_t rtc_ticks = pm_usec2rtc(s_sleep_duration, period); - if (sleep_rtc_ticks > WAKEUP_EARLY_TICKS + 1) { + if (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); + pm_set_sleep_mode(2); + pm_set_sleep_cycles(rtc_ticks - WAKEUP_EARLY_TICKS); rtc_light_sleep_start(s_sleep_wakup_triggers, 0); rtc_wakeup_init(); @@ -253,7 +315,7 @@ void esp_sleep_set_mode(esp_sleep_mode_t mode) void esp_sleep_start(void) { - if (cpu_is_wait_mode()) { + if (cpu_is_wait_mode() || cpu_reject_sleep()) { soc_wait_int(); return ; } @@ -266,7 +328,7 @@ void esp_sleep_start(void) const esp_irqflag_t irqflag = soc_save_local_irq(); const uint32_t wdevflag = save_local_wdev(); - if (cpu_is_wait_mode()) { + if (cpu_is_wait_mode() || cpu_reject_sleep()) { cpu_wait = 0; goto exit; } @@ -275,20 +337,18 @@ void esp_sleep_start(void) 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) { + uint32_t rtc_ticks = sleep_rtc_ticks(&clk); + if (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); + + 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, sleep_us); + update_soc_clk(&clk); cpu_wait = 0; } From ab0010dd1c20c80c6d52370b3509ba2ab4e4d87a Mon Sep 17 00:00:00 2001 From: Chen Wen Date: Thu, 19 Dec 2019 16:42:47 +0800 Subject: [PATCH 07/89] fix(lib): fix issue when scanning wpa2_enterprise authmode routers --- components/esp8266/lib/VERSION | 2 +- components/esp8266/lib/libnet80211.a | Bin 392516 -> 392576 bytes components/esp8266/lib/libnet80211_dbg.a | Bin 431908 -> 431964 bytes 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index 4e8fedcd6..b1d403e84 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -1,6 +1,6 @@ gwen: core: 27927af - net80211: a2ac2bd + net80211: 7fc008b pp: b01a3a6 wpa: 27927af espnow: 27927af diff --git a/components/esp8266/lib/libnet80211.a b/components/esp8266/lib/libnet80211.a index 24021b7e3f605731305d3e657ebcb1ee6acb5b20..c91c0f18a24a0e3dd7db59cf7c2ce44c1b1871f8 100644 GIT binary patch delta 2061 zcmbuAYfKbZ6vywKy|W-LEU=5aD&R8mepEm}pj$Dm#M&SbgqE~jA{0n#N)auVpcOWi zm^7%!N>4**(=;_cibP6fXoa#oLmTZQsfjg`G_`zaiVd~#0~(>{?%ZkcOJmascYgo# zzvrHFW|{0x-nX?ruyuqRw`8PdXXf-Pr&!BA!lwRx$%(;4PKp0-t7w79kF%;CC+Yv? zc-*P)4I~@fDMrifJWIC8A0yq-EY-+;`^mdT$ z^fgO%b$>05T%|jOQ_QaR)zhp1-Khw}9I2VU>!&+d)TW+y)8A#?@m20WM$aA>j*6$g zDbRx_s-#3o4=Spq=ho-}4sgMx2NgF~q@B1aRp|d^^^XL3NrHt%$trTeHyb z5@J$}jF{4=B|=DTgumBoZBI6pK<88JL{7`H7ZW6Dce;vj(NC@kXR)cM{zS8%0|&GfHNGo;NB=p!ttZL zY@=+iB4j)4M2QXRyetl9t!7VLa2ZB3H(`!Ib{X5Cu(GI$QItfo#L1$@4{i}K#%$>DIk)E~^^2MDrlu*oecdW{7PE?p7y{?Aho~5&e<7)s@+XuWEndQ{lA}PI}%UI?$cQ6wSMn{t$1F zvt5#1d;S@k9uq+nZK#8m-)9idT8xpp=o?W6!K8|Ix|jYU8${1Me2AWUOArlbeO_;L z?r)PElF{+BOAjR*9bCYfW~1Yoj|l6#CV7l+8L*>hF@H!aMi$UlrQVU!9~QI2yKCNN zI&|OtWmwaiy7~h?;KN*2XMJS54%zFU=-GEUK9j zOUc#MRXDMk^=*26HHc7B8+K72x8Zk-lyA*?ZnZ?+yZkg+Zre*=;bXhq6OMm75mASM(~Noc7_rnp{m#h(I;?!>@>}&v*XQfgPPkvMcA4mN}_)DnY z3eUH>Ec_hm@51vf^QI@qBBi3xX4D!iMnA?ke98r{5k6M%T0$xb9poW|Y!yKWbssCZ z8~fD5BM5Pe7|z^K7+^}AN1%E{9%w?8)FDtKBJN{{pnI*XXh#Cfw+_5!`Y7xkVx#bK z6m6l|TGv_j4K3b?!T9*CSS=^)`?=2z`;WNK3;R*-^Wl07p6G#dY^Rx?gxlxYOO$|D zV+}MKrntNciDM`(XhngRF~(qYjMdW+&2w!XSGl>j;^0O zKX*5|TNuY2Wfw6=D)e5&Sv4@rr3JDsq0EDqOEye#se#1HDDBY7#RbDC(w|R)G{GLB zK4_Xi`T-1ZnS&)1Se)R+CwcKnEcDJK7Ak`qlNb?#;vg%ahoLEh+MqMY5@gawh!YM5 z*#@~j5zkq8D2PMU39~_#EBo*WSOZHHHb|I4+6Y-wNc~7HI&I-}4|qB4N7@Ag@sbVB zaqNRBj_r0lU{D+@tx3Ssi7$fJf&SPbahl~)T@+}X#yNIq&>s_6Y_2hTz`zJxbor|tmcNt zXIO!8bK*6Rzpoi~pxq$GjsCL)iw!aZXQ7-R#`vF`wyRJcRE=Q$rp{`VpBnlbeJBC{ diff --git a/components/esp8266/lib/libnet80211_dbg.a b/components/esp8266/lib/libnet80211_dbg.a index da8afc7a446c00d3e1c21b588324d06c3ed72c27..b29b66fceb346e4fadf6d9551322a194d7563538 100644 GIT binary patch delta 2259 zcmbuAZERCj7{|}Ky{C+E$2!_=uyrq#IhZT#1-g|n)@`&wlx;*HA=*L2F<(+}28WBw zs53GU2O@<%7?Bu-K*AtS%C3p1ON`4fh>3#m0V9T&paBC!BFZv+o_o(t>L)Qax&8m1 z|MPOrJ-zAOe>CgD(X1VAd*z%`zrS+8^R^moVIuS|*FY~5@%{hpIu~K$L9W#gQuP07 zV%?>E#~!wO^5kvD#sV3~o_%OXmW+>$1*!@xu4#E&%0p#}CGWGe*{L)0} z&=|cs!t=)`8XfK2pKSHufK2_HD1URDbo7;*xnj4{#>lR1{QI{OCq!}-N7yoIS~3sj z{G}-HPN(8bF!ht2%Iplwpq)(Ksa$);GO$g@Hm4#DST`Ut^@dSpq4nGA=!_{)ouec> z)@@in>xGgsUuA{)T$uNIGTYYlitN{MtKaon!;F2WOjF0DSnJUSN=wyI>qw#T9Im(M zF*Q2LnsB;V%__2j-+I)Isn$5ERp(Ut%Au~APv-pJumLujL(-D{H;)ak6ZWXDQ?D zvHXy`?*p3(ZAWZL`q?Au8CR4u#**;rN5FkB4_<@FxURvUAUh=Syw(|_fWfW3Nh`Z zH-Yy^rrqvK@IOrO4<+!AlJBAZBKc3$mAD?wS8=U2g~6p1;p5%D-#o|1l3SWCg3HQM1aeSWcn<+;4k^-|eo{D3pn><83)8tdcvrIlu zTw?NN;!=}u5|^7is@Ii>C+&O>yyp`y^Sh83};V*CFIbnE|^=YT*jW3h>QEX@gB9Ti`5;!opBk zB^r4Fv{zxMt%6|+!;n4?i}t`8k~kbEc@;!8N(U?_xd;bHTHp>z976L^F2in;QMf|l z0$&YE5H^vt!Py#7%y$6~h-spK17krbLgapE2nhTOfp!$}{uIViW4HWHhzEp&kHA-y z{0MGP^5RCi`?Q^S_ug8}o`Ctan7s>YNGf0(im1`HLM5-AZX{{cc4nj^n?&1)v ztrwXPCd=UI;t(|&h5hInp=#{t%s<0XvnOQ%u1!5=(c%Thq-J#apgDXmS%Yu{EoCq_ zw!J0;uA?PxVUr(T+-!G2dJuP5l!yOK&|S=(P#wgUFf;^lc3D2zQ@v>SqMdSW3&sw{ zw&D}HIrdZ_+ddZ`)Y-|9JK5&p5x7B3-i3@sAPwm3L&BB#772%h7O`Fv_>P)nOU&+# Oi++!l#rMV!U;GW)TpCjV delta 2210 zcmbuAe@s(X6vyv{*A}ktp4jnQU z1T*XA*2rNABFRW*q7WE$?;mySN6buMzl@P&nz_tvZV@wGqWgimb6)RD>R)r&O>V#6 z^SS4od*5yIdSNJOU?}N8iZy5X@?5WPM0;Cp^Dt5VFLUHcCc;hsZJy6%;(liR{UrUr zoKU;Bd-NfzmL?xNbSE%pv@zpAl8i_11PankU)1pQ=hEwa9{##l29Vlqaq0dI{D)YR z>@F8bnt0j+_mGzDeC14&U<;Q%(Z=`1NTP4-;)>N=Hk!8X=V#wCiP5y#tvG5W2^BTC z-gp0{DDdts#TfjL0*d zNw!q)lr=gY@SC8yhjCi_0yV}S-O}q-r_HN0T2?%!zBb!z@Wlo-X^9zJ>r{6;qH0BM zt}ovQB~5&>e!N?q@gScKr;e(bd<*<~R6XtUElf%O$)g4@oSw-RdQxqr3s=pz&R|SS zwLDxeY_mI6#?E}%X<;_)G-tM)PDTT+9aG=TZ@)Xnm`%~D*Yh^Akx!el#4&%<-5jm? z#&hgOeKX%lYuSx=H785fv?mzf0dNGG z!aT;eON~Z<#eJ3~t%Q3f`h; z#fn>;4?{+rC~TuWLb9e8byRw~nQx`1r@kpY-OQiT(+$w1J!YV;l)ePD82991{J>Et zd9n1fBrjuZ4&%oug|Rg<2_ahp_ITm4S4vcYs1mXfW!FnoiHQ8H7tr9S!O1@~EZZt` zh;7wd;>ETkIB4ZwaC^ig*Wji{EQ5&{?&azFx-4;)Ke8xN7du%E;O7fBi*D-UH7T1gUMg2V&ve3UY1CaHy!B-_AVKuw>4jRn{=4hAXw zV2p)|mLl5x05QUh6jlzwO>`3fdTu7JA;g+Vik7fzDY zf;}KIc@Wm7aVJy;M4ae(nK2L41;hg3buspQWT_XI_-8N}5Q{|5T*e%s>v>MNO0*Yl z6Fq{|23s_ILVvMv@Gw*rBMu|p2_-ibCj^TzdmIiCUYd&8q3i-DTp(HiQ$%Z!rWl<) zB}i+)UxIWK(wRo?t4PIm4C9P&fWkc(#=^(#D&A}f?i+%ORCE|I2Y%3!0Pa%6has!f z#71#bDeiz*gft>9I1xb;l-Q5;s&N$CY9rCTT2gM5*CLHd>M+AtWAzx-48cjN8KRRI zbUH%qWk`QPnrG0;GR&P18;E+l@Z|yR-Bu^`BDOA>$Jn$3J}48K{ls4KjJ<)s(XLQk zAem>tZ7i~{FJNp8UvT?yp&>Ma3yDxwE;7v*J^qVnO;Im;`kT3;z(80em?@{i;u9@8 KrT4rT`{*A)CIw~y From 8801ba19f6057e1ce9f6c6b5cc54ca9920b4477f Mon Sep 17 00:00:00 2001 From: Zhang Jun Hao Date: Mon, 23 Dec 2019 11:38:26 +0800 Subject: [PATCH 08/89] feat(esp8266): set wifi default rx continuous buffer to 8 --- components/esp8266/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp8266/Kconfig b/components/esp8266/Kconfig index f1dcd4ebb..844bdf14e 100644 --- a/components/esp8266/Kconfig +++ b/components/esp8266/Kconfig @@ -391,7 +391,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 From 0f7eacd772da0f61cf7cf26c25db58eab3d8c2f1 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 23 Dec 2019 16:57:05 +0800 Subject: [PATCH 09/89] fix(util): fix sha384/512 data calculation overflow --- components/util/src/sha512.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/components/util/src/sha512.c b/components/util/src/sha512.c index 92230a27c..173a7c7eb 100644 --- a/components/util/src/sha512.c +++ b/components/util/src/sha512.c @@ -256,9 +256,10 @@ int esp_sha384_finish(esp_sha384_t *ctx, void *dest) ctx->buffer[used++] = 0x80; - memset(ctx->buffer + used, 0, 112 - used); - - if (used > 112) { + 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); } From ffaaf07089b8c4248badb17da89f2aff8d414444 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 24 Dec 2019 13:23:57 +0800 Subject: [PATCH 10/89] feat(mbedtls): mbedtls using SHA/AES of util component instead of its raw algorithm --- components/libsodium/Kconfig | 1 - .../crypto_hash_sha256_mbedtls.c | 10 -- .../crypto_hash_sha512_mbedtls.c | 13 --- components/mbedtls/Kconfig | 45 -------- .../mbedtls/port/include/mbedtls/esp_config.h | 19 --- components/util/include/esp_sha.h | 5 +- components/util/src/sha256.c | 109 ++++++++++-------- 7 files changed, 61 insertions(+), 141 deletions(-) diff --git a/components/libsodium/Kconfig b/components/libsodium/Kconfig index 58b33bdfb..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 !MBEDTLS_HARDWARE_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..9ffd28c60 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) @@ -55,7 +46,6 @@ static void sha256_libsodium_to_mbedtls(mbedtls_sha256_context *mb_ctx, crypto_h memcpy(mb_ctx->total, &ls_state->count, sizeof(mb_ctx->total)); memcpy(mb_ctx->state, ls_state->state, sizeof(mb_ctx->state)); memcpy(mb_ctx->buffer, ls_state->buf, sizeof(mb_ctx->buffer)); - mb_ctx->is224 = 0; } int 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..acb03849a 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) @@ -59,7 +47,6 @@ static void sha512_libsodium_to_mbedtls(mbedtls_sha512_context *mb_ctx, crypto_h memcpy(mb_ctx->total, ls_state->count, sizeof(mb_ctx->total)); memcpy(mb_ctx->state, ls_state->state, sizeof(mb_ctx->state)); memcpy(mb_ctx->buffer, ls_state->buf, sizeof(mb_ctx->buffer)); - mb_ctx->is384 = 0; } int diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index a1c396cf2..a8117c5fe 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -116,51 +116,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 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/util/include/esp_sha.h b/components/util/include/esp_sha.h index d929ead83..52a81a106 100644 --- a/components/util/include/esp_sha.h +++ b/components/util/include/esp_sha.h @@ -28,10 +28,9 @@ typedef struct { } esp_sha1_t; typedef struct { - uint64_t length; - uint32_t curlen; + uint32_t total[2]; uint32_t state[8]; - uint8_t buf[64]; + uint8_t buffer[64]; } esp_sha256_t; typedef struct { diff --git a/components/util/src/sha256.c b/components/util/src/sha256.c index bc585dad8..cc6de2bc7 100644 --- a/components/util/src/sha256.c +++ b/components/util/src/sha256.c @@ -79,7 +79,7 @@ static const uint32_t K[64] = { 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL }; -static void esp_sha256_transform(esp_sha256_t *ctx, uint8_t *buf) +static void esp_sha256_transform(esp_sha256_t *ctx, const uint8_t *buf) { uint32_t S[8], W[64], t0, t1; uint32_t t; @@ -108,8 +108,8 @@ int esp_sha256_init(esp_sha256_t *ctx) { util_assert(ctx); - ctx->curlen = 0; - ctx->length = 0; + ctx->total[0] = 0; + ctx->total[1] = 0; ctx->state[0] = 0x6A09E667UL; ctx->state[1] = 0xBB67AE85UL; @@ -127,8 +127,8 @@ int esp_sha224_init(esp_sha224_t *ctx) { util_assert(ctx); - ctx->curlen = 0; - ctx->length = 0; + ctx->total[0] = 0; + ctx->total[1] = 0; ctx->state[0] = 0xC1059ED8; ctx->state[1] = 0x367CD507; @@ -144,39 +144,43 @@ int esp_sha224_init(esp_sha224_t *ctx) int esp_sha256_update(esp_sha256_t *ctx, const void *src, size_t size) { - const uint8_t *in = (const uint8_t *)src; - uint32_t n; + size_t fill; + uint32_t left; + const uint8_t *input = (const uint8_t *)src; util_assert(ctx); util_assert(src); util_assert(size); - if (ctx->curlen >= sizeof(ctx->buf)) - return -1; - - while (size > 0) { - if (ctx->curlen == 0 && size >= 64) { - esp_sha256_transform(ctx, (uint8_t *) in); - - ctx->length += 64 * 8; - in += 64; - size -= 64; - } else { - n = MIN(size, (64 - ctx->curlen)); - memcpy(ctx->buf + ctx->curlen, in, n); - ctx->curlen += n; - in += n; - size -= n; - - if (ctx->curlen == 64) { - esp_sha256_transform(ctx, ctx->buf); - - ctx->length += 8 * 64; - ctx->curlen = 0; - } - } + 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; } @@ -191,37 +195,42 @@ int esp_sha224_update(esp_sha224_t *ctx, const void *src, size_t size) int esp_sha224_finish(esp_sha224_t *ctx, void *dest) { - int i; + uint32_t used; + uint32_t high, low; uint8_t *out = (uint8_t *)dest; util_assert(ctx); util_assert(dest); - if (ctx->curlen >= sizeof(ctx->buf)) - return -1; - - ctx->length += ctx->curlen * 8; + used = ctx->total[0] & 0x3F; - ctx->buf[ctx->curlen++] = 0x80; + ctx->buffer[used++] = 0x80; - if (ctx->curlen > 56) { - while (ctx->curlen < 64) - ctx->buf[ctx->curlen++] = 0; - - esp_sha256_transform(ctx, ctx->buf); - ctx->curlen = 0; + 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); } - while (ctx->curlen < 56) - ctx->buf[ctx->curlen++] = 0; + high = (ctx->total[0] >> 29) | (ctx->total[1] << 3); + low = (ctx->total[0] << 3); - ESP_PUT_BE64(ctx->buf + 56, ctx->length); - esp_sha256_transform(ctx, ctx->buf); + ESP_PUT_BE32(ctx->buffer + 56, high); + ESP_PUT_BE32(ctx->buffer + 60, low); - for (i = 0; i < 7; i++) - ESP_PUT_BE32(out + (4 * i), ctx->state[i]); + esp_sha256_transform(ctx, ctx->buffer); - return 0; + 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]); + + return( 0 ); } int esp_sha256_finish(esp_sha256_t *ctx, void *dest) From 5a0e946af2293b0099f8693b6b4d6bfb7d665a02 Mon Sep 17 00:00:00 2001 From: chenjianqiang Date: Wed, 25 Dec 2019 21:53:56 +0800 Subject: [PATCH 11/89] bugfix(flash): add support for GD25Q64 qio enable --- components/spi_flash/src/spi_flash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; } From c13552e4a9f1ee101dcaa27c5f09c00921df13d9 Mon Sep 17 00:00:00 2001 From: Krzysztof Date: Sun, 22 Dec 2019 12:37:25 +0800 Subject: [PATCH 12/89] doc: Limit sphinxcontrib versions to <2.0.0 as we use Sphinx 1.8.5 --- docs/requirements.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 3676a3c39..0c623e4cd 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -5,9 +5,9 @@ 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 recommonmark future>=0.16.0 # for ../tools/gen_esp_err_to_name.py From 14f85a6c4e1e9d6b3e25ea7f9cd24c44b7639b46 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Fri, 27 Dec 2019 14:14:40 +0800 Subject: [PATCH 13/89] fix(mbedtls): fix option dependence of "MBEDTLS_SERVER_SSL_SESSION_TICKETS" MBEDTLS_SERVER_SSL_SESSION_TICKETS -> MBEDTLS_CIPHER_MODE_AEAD -> MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C --- components/mbedtls/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index a1c396cf2..3f69ef8da 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -366,6 +366,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. From d1f1becd144df8790fb09e1ea57fac2ce72a0cd9 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Thu, 26 Dec 2019 10:30:37 +0800 Subject: [PATCH 14/89] fix(esp-wolfssl): fix esp-wolfssl cmake compiling error --- components/esp-wolfssl/CMakeLists.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) 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() From b19da4ffcd94643be2bacd9f3dd65fb4c9eaa382 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 30 Dec 2019 19:31:17 +0800 Subject: [PATCH 15/89] feat(util): support SHA224/SHA384 calculation although call sha256/sha512 APIs --- .../crypto_hash_sha256_mbedtls.c | 1 + .../crypto_hash_sha512_mbedtls.c | 1 + components/util/include/esp_sha.h | 4 ++++ components/util/src/sha256.c | 12 ++++++++---- components/util/src/sha512.c | 14 +++++++++----- 5 files changed, 23 insertions(+), 9 deletions(-) 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 9ffd28c60..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 @@ -46,6 +46,7 @@ static void sha256_libsodium_to_mbedtls(mbedtls_sha256_context *mb_ctx, crypto_h memcpy(mb_ctx->total, &ls_state->count, sizeof(mb_ctx->total)); memcpy(mb_ctx->state, ls_state->state, sizeof(mb_ctx->state)); memcpy(mb_ctx->buffer, ls_state->buf, sizeof(mb_ctx->buffer)); + mb_ctx->is224 = 0; } int 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 acb03849a..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 @@ -47,6 +47,7 @@ static void sha512_libsodium_to_mbedtls(mbedtls_sha512_context *mb_ctx, crypto_h memcpy(mb_ctx->total, ls_state->count, sizeof(mb_ctx->total)); memcpy(mb_ctx->state, ls_state->state, sizeof(mb_ctx->state)); memcpy(mb_ctx->buffer, ls_state->buf, sizeof(mb_ctx->buffer)); + mb_ctx->is384 = 0; } int diff --git a/components/util/include/esp_sha.h b/components/util/include/esp_sha.h index 52a81a106..238d1be12 100644 --- a/components/util/include/esp_sha.h +++ b/components/util/include/esp_sha.h @@ -31,12 +31,16 @@ typedef struct { uint32_t total[2]; uint32_t state[8]; uint8_t buffer[64]; + + int is224; } esp_sha256_t; typedef struct { uint64_t total[2]; uint64_t state[8]; uint8_t buffer[128]; + + int is384; } esp_sha512_t; typedef esp_sha256_t esp_sha224_t; diff --git a/components/util/src/sha256.c b/components/util/src/sha256.c index cc6de2bc7..3b658beb9 100644 --- a/components/util/src/sha256.c +++ b/components/util/src/sha256.c @@ -108,6 +108,8 @@ int esp_sha256_init(esp_sha256_t *ctx) { util_assert(ctx); + ctx->is224 = 0; + ctx->total[0] = 0; ctx->total[1] = 0; @@ -127,6 +129,8 @@ int esp_sha224_init(esp_sha224_t *ctx) { util_assert(ctx); + ctx->is224 = 1; + ctx->total[0] = 0; ctx->total[1] = 0; @@ -230,19 +234,19 @@ int esp_sha224_finish(esp_sha224_t *ctx, void *dest) 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) { - uint8_t *out = (uint8_t *)dest; - util_assert(ctx); util_assert(dest); esp_sha224_finish(ctx, dest); - ESP_PUT_BE32(out + 28, ctx->state[7]); - return 0; } diff --git a/components/util/src/sha512.c b/components/util/src/sha512.c index 173a7c7eb..61faf2c18 100644 --- a/components/util/src/sha512.c +++ b/components/util/src/sha512.c @@ -159,6 +159,8 @@ int esp_sha512_init(esp_sha512_t *ctx) { util_assert(ctx); + ctx->is384 = 0; + ctx->total[0] = 0; ctx->total[1] = 0; @@ -178,6 +180,8 @@ int esp_sha384_init(esp_sha384_t *ctx) { util_assert(ctx); + ctx->is384 = 1; + ctx->total[0] = 0; ctx->total[1] = 0; @@ -279,20 +283,20 @@ int esp_sha384_finish(esp_sha384_t *ctx, void *dest) 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) { - uint8_t *output = (uint8_t *)dest; - util_assert(ctx); util_assert(dest); esp_sha384_finish(ctx, dest); - PUT_UINT64_BE(ctx->state[6], output, 48); - PUT_UINT64_BE(ctx->state[7], output, 56); - return 0; } From 49a065de6343207ea6f9821aab25e9b2f1473e33 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 6 Jan 2020 17:35:05 +0800 Subject: [PATCH 16/89] fix(esp8266): fix Wi-Fi initialization data error when compiling cpp --- components/esp8266/include/esp_wifi.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/esp8266/include/esp_wifi.h b/components/esp8266/include/esp_wifi.h index a8bde5175..d132131b3 100644 --- a/components/esp8266/include/esp_wifi.h +++ b/components/esp8266/include/esp_wifi.h @@ -156,15 +156,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,\ From c3019b8103f1458d46fbbecf61d3fe5ab028ba2d Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Thu, 2 Jan 2020 19:17:41 +0800 Subject: [PATCH 17/89] fix(esp8266): fix light sleep time error when waking up --- components/esp8266/include/driver/rtc.h | 4 +- components/esp8266/source/esp_sleep.c | 212 ++++++++++++++---------- 2 files changed, 131 insertions(+), 85 deletions(-) diff --git a/components/esp8266/include/driver/rtc.h b/components/esp8266/include/driver/rtc.h index 913be713f..b9adc9c15 100644 --- a/components/esp8266/include/driver/rtc.h +++ b/components/esp8266/include/driver/rtc.h @@ -109,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 @@ -119,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/source/esp_sleep.c b/components/esp8266/source/esp_sleep.c index dd0068a93..2eadab8b9 100644 --- a/components/esp8266/source/esp_sleep.c +++ b/components/esp8266/source/esp_sleep.c @@ -39,7 +39,7 @@ #define FRC2_TICKS_PER_US (5) #define FRC2_TICKS_MAX (UINT32_MAX / 4) -#define SLEEP_PROC_TIME (3072) +#define SLEEP_PROC_TIME (2735) #define WAKEUP_EARLY_TICKS (264) // PLL and STAL wait ticks #define MIN_SLEEP_US (6500) #define RTC_TICK_CAL (100) @@ -61,6 +61,14 @@ typedef struct pm_soc_clk { 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; @@ -82,6 +90,16 @@ 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); @@ -120,7 +138,7 @@ static inline uint32_t sleep_rtc_ticks(pm_soc_clk_t *clk) clk->cal_period = pm_rtc_clock_cali_proc(); - rtc_ticks = pm_usec2rtc(clk->sleep_us - SLEEP_PROC_TIME, clk->cal_period); + rtc_ticks = rtc_us_to_clk(clk->sleep_us - SLEEP_PROC_TIME, clk->cal_period); return rtc_ticks; } @@ -129,18 +147,24 @@ static inline void update_soc_clk(pm_soc_clk_t *clk) { extern uint32_t WdevTimOffSet; - uint32_t slept_us, total_rtc, 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 = pm_rtc2usec(total_rtc, clk->cal_period) + RTC_TICK_OFF; + uint32_t slept_us; - if (slept_us > clk->sleep_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; - else - slept_us -= RTC_TICK_CAL; + } const uint32_t os_ccount = slept_us * g_esp_ticks_per_us + clk->ccount; @@ -196,16 +220,6 @@ static int cpu_reject_sleep(void) return ret; } -void esp_wifi_hw_open(void) -{ - phy_open_rf(); -} - -void esp_wifi_hw_close(void) -{ - phy_close_rf(); -} - rtc_cpu_freq_t rtc_clk_cpu_freq_get(void) { rtc_cpu_freq_t freq; @@ -232,7 +246,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; @@ -265,35 +279,104 @@ 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 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 (rtc_ticks > WAKEUP_EARLY_TICKS + 1) { - const rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get(); + if (cpu_reject_sleep()) { + if (proc->wait_int) + soc_wait_int(); + return ESP_ERR_INVALID_STATE; + } - pm_set_sleep_mode(2); - pm_set_sleep_cycles(rtc_ticks - WAKEUP_EARLY_TICKS); - rtc_light_sleep_start(s_sleep_wakup_triggers, 0); - rtc_wakeup_init(); + if (proc->flush_uart) { + uart_tx_wait_idle(0); + uart_tx_wait_idle(1); + } - rtc_clk_cpu_freq_set(cpu_freq); + irqflag = soc_save_local_irq(); + wdevflag = save_local_wdev(); - ret = ESP_OK; - } else { + if (proc->check_mode && cpu_is_wait_mode()) { + ret = ESP_ERR_INVALID_ARG; + goto exit; + } + + 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 + }; + + return esp_light_sleep_internal(&proc); +} + void esp_sleep_lock(void) { const esp_irqflag_t irqflag = soc_save_local_irq(); @@ -315,49 +398,12 @@ void esp_sleep_set_mode(esp_sleep_mode_t mode) void esp_sleep_start(void) { - if (cpu_is_wait_mode() || cpu_reject_sleep()) { - 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_reject_sleep()) { - 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 rtc_ticks = sleep_rtc_ticks(&clk); - if (rtc_ticks > WAKEUP_EARLY_TICKS + 1) { - const 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; - } - } - -exit: - restore_local_wdev(wdevflag); - soc_restore_local_irq(irqflag); - - if (cpu_wait) - soc_wait_int(); + const sleep_proc_t proc = { + .sleep_us = 0, + .wait_int = 1, + .check_mode = 1, + .flush_uart = 1, + }; + + esp_light_sleep_internal(&proc); } From 92a3f40c7b4c951397e7887afcb9214d73a7b4d8 Mon Sep 17 00:00:00 2001 From: Zhang Jun Hao Date: Mon, 6 Jan 2020 18:01:24 +0800 Subject: [PATCH 18/89] fix(esp8266): fix compile failed when CONFIG_ESP8266_WIFI_CONNECT_OPEN_ROUTER_WHEN_PWD_IS_SET is unset --- components/esp8266/source/esp_wifi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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); From 1193d2eb3c114ca261b1b4fdb809440b66e7a0eb Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 7 Jan 2020 14:35:17 +0800 Subject: [PATCH 19/89] fix(esp-mqtt): fix esp-mqtt API declare error --- components/mqtt/esp-mqtt/include/mqtt_client.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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); From 81d3baafa5bd2fe0ba0ba3337830db42c3af6f30 Mon Sep 17 00:00:00 2001 From: yuanjm Date: Tue, 7 Jan 2020 15:39:52 +0800 Subject: [PATCH 20/89] feat(ipv6): Enable ipv6 autoconfig function in lwip port level --- components/lwip/port/esp8266/netif/ethernetif.c | 4 ++++ 1 file changed, 4 insertions(+) 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 */ } /* From a1e4aa22f780ca80a28baa32054f70d6b63607ee Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Wed, 8 Jan 2020 09:47:45 +0800 Subject: [PATCH 21/89] feat(newlib): add "sys/un.h" header file --- .../newlib/newlib/port/include/sys/un.h | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 components/newlib/newlib/port/include/sys/un.h 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 */ +}; From d3cf562b665d5e1113b3010b4cb09c66304e756b Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Wed, 8 Jan 2020 10:47:30 +0800 Subject: [PATCH 22/89] feat(tcpip_adapter): add header file and wrapper APIs to make code compatible with "esp_netif" --- components/tcpip_adapter/esp_netif.c | 27 +++++++++ components/tcpip_adapter/include/esp_netif.h | 58 ++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 components/tcpip_adapter/esp_netif.c create mode 100644 components/tcpip_adapter/include/esp_netif.h 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 From 1f2ae589dbcbf418ba953cb906eb886f2c896421 Mon Sep 17 00:00:00 2001 From: espressif Date: Thu, 9 Jan 2020 17:02:37 +0800 Subject: [PATCH 23/89] bugfix(uart_interrupt_occupy):disable intr that you are not using --- components/esp8266/driver/uart.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/esp8266/driver/uart.c b/components/esp8266/driver/uart.c index 728c84589..93c82e08c 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); From 34a1554f198176028bc32fd0235a4c90854c8f37 Mon Sep 17 00:00:00 2001 From: espressif Date: Fri, 10 Jan 2020 15:25:52 +0800 Subject: [PATCH 24/89] bugfix(gpio_set_pull_mode_error):fix cant set gpio pull mode --- components/esp8266/driver/gpio.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) 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)); From cd03c0cc22cc0e1322aa4a84f016b808985f9d14 Mon Sep 17 00:00:00 2001 From: Supreet Deshpande Date: Thu, 9 Jan 2020 15:55:52 +0530 Subject: [PATCH 25/89] bugfix/tls_handshake: Fixed an error check during TLS handshake. (cherry picked from commit fb8b45cf0665d7cca1415430a22c1d74d17d9827) --- components/aws_iot/port/network_mbedtls_wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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); } From 6c806c48fc7c77b4f5b287fdd4ae614e38debf92 Mon Sep 17 00:00:00 2001 From: dongheng Date: Mon, 17 Feb 2020 10:00:37 +0800 Subject: [PATCH 26/89] fix(requirements): fix read the docs compiling requirements error --- docs/requirements.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/requirements.txt b/docs/requirements.txt index 0c623e4cd..f3884f2ee 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -9,5 +9,9 @@ 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 From 465b6a5abd056f23d2a20d34f96797cfffde73bc Mon Sep 17 00:00:00 2001 From: dongheng Date: Mon, 17 Feb 2020 11:24:30 +0800 Subject: [PATCH 27/89] fix(esp-tls): fix esp-tls compiling error Closes https://github.com/espressif/ESP8266_RTOS_SDK/issues/828 --- components/esp-tls/esp_tls_mbedtls.c | 4 ++-- examples/protocols/https_request/sdkconfig.ci | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 examples/protocols/https_request/sdkconfig.ci diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index 823fa6dbf..702d2b81e 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -470,8 +470,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/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 From 7493693fc92415c2c4242c2a744f55fe692c2afb Mon Sep 17 00:00:00 2001 From: donghengqaz <930490596@qq.com> Date: Thu, 13 Feb 2020 14:08:14 +0800 Subject: [PATCH 28/89] fix(example): fix HTTPS request SSL macro error --- .../https_request/main/https_request_example_main.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) 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..e8057f414 100644 --- a/examples/protocols/https_request/main/https_request_example_main.c +++ b/examples/protocols/https_request/main/https_request_example_main.c @@ -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) From c5b9083d484af62374af21576023138db57964b7 Mon Sep 17 00:00:00 2001 From: dongheng Date: Tue, 25 Feb 2020 13:51:14 +0800 Subject: [PATCH 29/89] fix(esp8266): fix deep sleep fail --- components/esp8266/lib/VERSION | 2 +- components/esp8266/lib/libcore.a | Bin 91906 -> 91714 bytes components/esp8266/lib/libcore_dbg.a | Bin 93174 -> 92978 bytes 3 files changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 components/esp8266/lib/libcore.a mode change 100644 => 100755 components/esp8266/lib/libcore_dbg.a diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index b1d403e84..1cc3772ce 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -1,5 +1,5 @@ gwen: - core: 27927af + core: e2b9f8c net80211: 7fc008b pp: b01a3a6 wpa: 27927af diff --git a/components/esp8266/lib/libcore.a b/components/esp8266/lib/libcore.a old mode 100644 new mode 100755 index 350865e9f1ea0d7c7fb8cf37135931572863f503..43954e44b7faaf29aa8674acbe406965890930cb GIT binary patch delta 9879 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 delta 10037 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 WN~QZvq(Kk4;Xj=1UDlva_xpb{&1=LsL;{ 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 delta 10220 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 From d3b17b53b87d83383766a729ad83b0b81f4fe8b7 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Thu, 27 Feb 2020 10:22:48 +0800 Subject: [PATCH 30/89] chore(ci): modify CI test SSC branch to be "release/v3.3_8266" for backport --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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: From 7bee7e695451b9eead00a01ff179fe2de530def1 Mon Sep 17 00:00:00 2001 From: Zhang Jun Hao Date: Mon, 2 Mar 2020 17:37:49 +0800 Subject: [PATCH 31/89] fix(wifi): fix writting error --- components/esp8266/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp8266/Kconfig b/components/esp8266/Kconfig index 844bdf14e..825dd8c5b 100644 --- a/components/esp8266/Kconfig +++ b/components/esp8266/Kconfig @@ -420,7 +420,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 From bf8a9800cb03239f9511864a5aec698f5951a308 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 16 Mar 2020 13:57:46 +0800 Subject: [PATCH 32/89] fix(lib): fix sleep error when period cal called --- components/esp8266/lib/VERSION | 2 +- components/esp8266/lib/libpp.a | Bin 264476 -> 262952 bytes components/esp8266/lib/libpp_dbg.a | Bin 284848 -> 283308 bytes 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index 1cc3772ce..621c9654f 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -1,7 +1,7 @@ gwen: core: e2b9f8c net80211: 7fc008b - pp: b01a3a6 + pp: 5e3fa03 wpa: 27927af espnow: 27927af wps: 27927af diff --git a/components/esp8266/lib/libpp.a b/components/esp8266/lib/libpp.a index 3651cb87ea99270240fa9c45a42fbe77dc96f563..9dd7820c9c4ad58f41531c0779efef47f49aab9a 100644 GIT binary patch delta 26012 zcmc(I33OG}+4kNiH-T_&Aj5?a#+v~Q%8-O0L8gEZ5(N!|hzJr=CY4Euh>Bb&h^VMQ zkd1-}NEIzb1oTorYa>zwM2pl~v`W#UbwI0V9op*spJ$)<;N^aP>tE|%>+8SQ+GjuS z^S=AtN z%K2Z8NvUBK7bEe){|6j7r#AnI3QV3mWx|~K6KZdqGGXHM>APD5zDeF)(BzXQt*8Lo zbyhd;j4$rtuMPFjmuK%D(EP>=8vD%d=gZ5Af0TZ>VcmmgrRc_>KJA

wmZ*JJ7SJ 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 diff --git a/components/esp8266/lib/libpp_dbg.a b/components/esp8266/lib/libpp_dbg.a index 8bf8759d554c236958ffe7a93875d8e074026c57..c6af2f1f95556c79ebf7f5920a5e026bbb0bb917 100644 GIT binary patch delta 36039 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 Pj@8%2Rj$4+KB)d5kQqCk delta 37378 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 From 407aea72ddec391287cd54a356fd767f79641c0e Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 16 Mar 2020 14:04:19 +0800 Subject: [PATCH 33/89] fix(lib): do not connect to ap when set country called --- components/esp8266/lib/VERSION | 2 +- components/esp8266/lib/libnet80211.a | Bin 392576 -> 392468 bytes components/esp8266/lib/libnet80211_dbg.a | Bin 431964 -> 431856 bytes 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index 621c9654f..03d89fc56 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -1,6 +1,6 @@ gwen: core: e2b9f8c - net80211: 7fc008b + net80211: 3a13410 pp: 5e3fa03 wpa: 27927af espnow: 27927af diff --git a/components/esp8266/lib/libnet80211.a b/components/esp8266/lib/libnet80211.a index c91c0f18a24a0e3dd7db59cf7c2ce44c1b1871f8..ff4f340b75fbc203aa783d753610c4f9c45bc1b1 100644 GIT binary patch delta 5444 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 YH{JgvS|+BO-nILxw0ZHRrg;bc0ShoN(*OVf delta 5546 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 delta 5556 zcmc(jeNa@_6~OO#yNlp1vI~S=5ODYL4T~%&iUu7(G-?o`O;R(1RSdDt6u+k0IK}ud zV~9>MVxDqs#y`+%#!fW@vyN*zwt_VYnb8y+8?~hgW{8pM7&Ru<)^U5z`!JV8+v>E_ zJ9FOo-QPX;-uK?V-KShXlr->mQd`of$&)5e43v~~`Bs3kiGlwyW1)k=gQ5{V#oF0= zD7zU@yjICzYt_h5zAYZmmr_dEV@K02CjE<0w88C{ne^X?yU9#?Kv+D@%rbV@gF<1Ba0lbd4!S_@gc?wrjTY-@-~;M<06HsxA4P_w2;Vo_Zm>>1v8vwoEC^KilpCmxUFOYco* znQN0Wi&HY6@RkpS3qK3X9RQz)yBU-BNV6t0M`?t_n8V+~7&~pN|2TYm*5&8CFR&c& z4TQ6$B5C*gs??IlWQi^LNXl`^5%U}tN4$52I?W+>*q78R68w>tTjrA^s*V)d;SBZk zW4;6WskgLrdTZDr$tz3qW8gHI7TomI@)8JKiklU|TCd^YiqiZs@IDQ`XJJcI9NFN# z6z4kn(xi5K`Yy#eq{zZv-+5PTk2Cr@!xr0f{R3ZAq4$Ir?uLVj8`gnyEq)q!#t~E5 zb4$Vr*OvT+pnzq5+qR#CQ{9IZu@=?q^3M z${4XUhK+`aV=?2MXX%0`rdv$)MaVQx^%Idx4Bv}U$74QVum`gh=a8rCiZR%a*=I1FKlQ1`iuDBs(_S=2J{f%jV-Z@XQC&UkhDLSE za2mX+9vaS4I*sj)U=AAmB2G<5hHgAy>%*X>$PwGS@qq2m807zoIU57^;Q`yn805(j z+YRqWhW&WJHiUsS3L{A!yD<zkt4Pn{-)vS8ox3)lCBvUF5v;&Jq(&l zj@WK^sw1yGE1>8ddO+wwFei^SipUY0lc`Qy6!TPr>26gT{C&)&w9XzpV0+5&-XtuDNA+(lnhiuioSW@4@m=HGNak%5l}wL1JlgTc!LUZXKz zG71*)VZY6hn5NfXC2#O;jro{-TY-|H4^PCOA27H~;3|O^2;4xNsn1;{@Opta3%o<% z4&p3*Ztg*$b5!7y0{3ame-{a93f^n2#o!tSI|TL!oKBphmj?tc6?nG5&j`GjI9H$B zC~)dJp|eTgHjVj)C@9Ft)90NcW$<}{hcxDAqTtC4zh3Ic=MxMr5x7!gUNjoEDfxQo zASr{d3Vd5&s|#z!>-A27lLgKec%r~%#0C1?DuGiM2%QFjS82?DXa~0v(C6(SWpIbU z2L(P#T&UNd6u3{|0f8?Ie2ch9pGz-PlNE>1@d%tQaDaG%KDkuj*#bW!@M3`*iRl*` z+d6?a>5RYD*xH1F-NeP3W(Nd5EO58Lr-V? zN<2-kzfD}GvlV~PL*3DEJqqsfE;r1FWgI-1HuG9clJiBr*8|nOED@~ymItbEpga-B zJNR}=jr<~|I$oHB)z)SFl_aP}+mBsX&wXPtmGIS+>Ua+(iLKLlq&f!rB*)0hiQ;+@j)Imsr8HEc&`tfw$e@bqU3+^K^m;$AVU_c<2jU0@>)!` zUN>WjYWb8n-X?=n@^9vQWyrJ*p?+P{gQP1r^P8mC;0tbsrUPlH%eL@}G}K2?4{5p? zwQa{1#&+?YX^>{yoygd1^~SV#7rwpe#cq5k%>Q%#DNP;1g6Da8s}%42Rt4VhbUeW_ z{P*izek0%dor2qZBNen_!L!=t-Ra=OPo$sh5ZW2qZE$AbnL4&|IRm%L#`m#DD_)Em z8u;oA+5@eu*-o;Xc@NnJw7F#4Gg0<&S0>6fl(kxE4O%I^jW5Zh%RoIr(;ZZNfOk=` zCxx+cUi+3M-idE2@$&C-{0Opaby!fQO)Ja7X`Q^5>~6Hq-qYPx@Vmo+wHrlKAZ8O<}d^_2@Xp^)p`pBN-7s+~38B5TtHwW!4 zUYLV6fOd>#SD}?0Dt{#hGGRLR<${}cQ)LJ+e%7ZK^UFB2rAT#16FJsPlzBCWyh?6@tejOQJ<6T&WH|+wY zK@NV%G5=p4D)hs~fZ5|+J1w42e;r&Lb6>e;+ED!%Qldtx=(SKh`o6+tJfV68wu~}W z=tc`bgxS+qc5Q|JZTFS7GNee+b*7@f5`;SMNFee2CdoBI*ELB+38vxN+(X-?&wgYo zb8f6O!VLaHnw31l)O6V{OS~^x8XdFZr#~6LvY@co_$#M=k_*RL=Kai^5yCst-)i>s zf<3a;7Hulr))RWSz Date: Mon, 16 Mar 2020 15:35:12 +0800 Subject: [PATCH 34/89] feat(tcpip_adapter): add AP assigned IP event data --- components/esp8266/include/esp_event.h | 6 ++++++ components/tcpip_adapter/tcpip_adapter_lwip.c | 1 + examples/wifi/simple_wifi/main/simple_wifi.c | 4 ++++ 3 files changed, 11 insertions(+) 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/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/examples/wifi/simple_wifi/main/simple_wifi.c b/examples/wifi/simple_wifi/main/simple_wifi.c index 975d393e0..e92bd64d2 100644 --- a/examples/wifi/simple_wifi/main/simple_wifi.c +++ b/examples/wifi/simple_wifi/main/simple_wifi.c @@ -70,6 +70,10 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) 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; } From 30c62c6fd35edda7ba84002777a5bdd2de0fe12a Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 24 Mar 2020 12:05:17 +0800 Subject: [PATCH 35/89] feat(phy): update phy library from 1155.0 to 1156.0 1. fix bug in calibration 2. reduce RAM cost 3. reduce current when RF is closed --- components/esp8266/lib/VERSION | 2 +- components/esp8266/lib/libphy.a | Bin 264454 -> 262908 bytes components/esp8266/lib/librtc.a | Bin 4972 -> 5056 bytes .../components/rf_test/lib/librftest.a | Bin 72002 -> 70190 bytes 4 files changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index 03d89fc56..9a90de1b1 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -8,4 +8,4 @@ gwen: wpa2: 27927af smartconfig: 2.8.2 - phy: 1155.0 + phy: 1156.0 diff --git a/components/esp8266/lib/libphy.a b/components/esp8266/lib/libphy.a index e9c9cef90c1ee27a50347180288e201471adb738..7a4c2ea4fdc3360b6d9940de9f8cf966ef80ca52 100755 GIT binary patch delta 66452 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 BaQ^@R delta 68433 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 Cs<7?= diff --git a/components/esp8266/lib/librtc.a b/components/esp8266/lib/librtc.a index b099d1f70d3a417c98442173ef90b4656c95ccc8..0aeca762535e734b2980d378e5c7e3a3dea11881 100755 GIT binary patch delta 559 zcmaE(c0hfC6uX6yp@o@+;YLMPMi_gtE~5mqxskzS4@M2f8Iubcz1bMfI4d#vY(B&& z#VE%B1c874JFP!(K!G8HRp{Uc2R8vu!;^{%DhiI@Cx2m5kU7hw`2IhSs0I^{Ns^M9 zEvwRkqyuaW9EQ3)Cln`(F)v{h*u0xrno(2$XcVIc0|SVT24W^4&Yt|5#Yo$jK`$q> zB(*3p$4Jk}%mjsJio!FSEWj#0`5~*sZj0ph$0exQp delta 487 zcmY*TO-lk%6n*#EjNhQ6g&2jYI7%dq%4iUl_CX*hE`t^s2?-J?E?Tq=S|)c9v@(cj zS2AtdS+uKPP_0@Q*d`)~x&s<|;GBETeQ@6G$Zw$|uQ3@HTrX8)(U_VVN^^rLIXje;|AZiV@K~74P*uHLEkzsU zy+*HWC{x{F)(eNSqJ0Wa+}^)YVs3V#y_*o4S7X?+NZPe!ldJl(TO=X)iMk)5X(B>| zgpelcdwr*SYed_!=M50VwxhtiX5`L1q_F5Lzy_X@ZsUh@8ge)x1%yK@WAnHo1>gZI xk_;j?Nz-^E$^71muTlth(d?4Jh6?F9uDfL6g-&SUfh*wIH!^ks^l1-$`v)c^aW?<} 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 63d15ca7b647445e7d57e5f5928c3c9fb84d3e58..a07870449ef52a609287b7ba0d19475b9acb5d12 100755 GIT binary patch delta 17275 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 delta 18918 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 Ai2wiq From 417a6078a8168951a0a9e2b69996409c7bc65ef7 Mon Sep 17 00:00:00 2001 From: yuanjm Date: Thu, 26 Mar 2020 11:58:18 +0800 Subject: [PATCH 36/89] feat(lwip): Add kconfig to congigure initial RTO time and set default value to 1000 --- components/lwip/Kconfig | 7 +++++++ components/lwip/lwip/src/core/tcp.c | 5 +++-- components/lwip/lwip/src/include/lwip/opt.h | 5 +++++ components/lwip/port/esp8266/include/lwipopts.h | 6 ++++++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index 0006c0068..3f4422495 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -479,6 +479,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/lwip/src/core/tcp.c b/components/lwip/lwip/src/core/tcp.c index fba9d99e6..3af362d73 100644 --- a/components/lwip/lwip/src/core/tcp.c +++ b/components/lwip/lwip/src/core/tcp.c @@ -1630,8 +1630,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/port/esp8266/include/lwipopts.h b/components/lwip/port/esp8266/include/lwipopts.h index 970ac342e..60eaf9e70 100644 --- a/components/lwip/port/esp8266/include/lwipopts.h +++ b/components/lwip/port/esp8266/include/lwipopts.h @@ -1097,6 +1097,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 /** * @} */ From bc6834b2a2c4a1fa7352446692e19a71d4168964 Mon Sep 17 00:00:00 2001 From: Zhang Jun Hao Date: Fri, 20 Mar 2020 10:00:33 +0800 Subject: [PATCH 37/89] feat(pm): refactor power management according to IDF --- components/esp8266/Kconfig | 12 ++++++++++ components/esp8266/include/esp_sleep.h | 19 +++++++++++++-- components/esp8266/include/esp_wifi.h | 10 ++++++++ components/esp8266/include/esp_wifi_types.h | 23 +++++++++++++++++-- .../include/internal/esp_wifi_internal.h | 16 +++++++++++++ components/esp8266/source/esp_sleep.c | 20 ++++++++++++++++ components/esp8266/source/startup.c | 6 +++++ examples/wifi/power_save/README.md | 6 ++--- examples/wifi/power_save/main/power_save.c | 10 +++++++- 9 files changed, 114 insertions(+), 8 deletions(-) diff --git a/components/esp8266/Kconfig b/components/esp8266/Kconfig index 825dd8c5b..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 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 d132131b3..ab156f62f 100644 --- a/components/esp8266/include/esp_wifi.h +++ b/components/esp8266/include/esp_wifi.h @@ -977,6 +977,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..91f2ca88f 100644 --- a/components/esp8266/include/internal/esp_wifi_internal.h +++ b/components/esp8266/include/internal/esp_wifi_internal.h @@ -175,6 +175,22 @@ 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); + #ifdef __cplusplus } #endif diff --git a/components/esp8266/source/esp_sleep.c b/components/esp8266/source/esp_sleep.c index 2eadab8b9..bc3e7b377 100644 --- a/components/esp8266/source/esp_sleep.c +++ b/components/esp8266/source/esp_sleep.c @@ -18,6 +18,7 @@ #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" @@ -374,6 +375,10 @@ esp_err_t esp_light_sleep_start(void) .flush_uart = 1 }; + if (esp_wifi_get_state() >= WIFI_STATE_START) { + return ESP_ERR_INVALID_STATE; + } + return esp_light_sleep_internal(&proc); } @@ -407,3 +412,18 @@ void esp_sleep_start(void) esp_light_sleep_internal(&proc); } + +esp_err_t esp_pm_configure(const void* vconfig) +{ +#ifndef CONFIG_PM_ENABLE + return ESP_ERR_NOT_SUPPORTED; +#endif + + 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; + } + return ESP_OK; +} 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/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..f181ad231 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" @@ -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) From cfadb3b531b60319d1ca22fa7cfccc8664b7923b Mon Sep 17 00:00:00 2001 From: Zhang Jun Hao Date: Fri, 20 Mar 2020 17:27:33 +0800 Subject: [PATCH 38/89] feat(lib): update library --- components/esp8266/lib/VERSION | 6 +++--- components/esp8266/lib/libcore.a | Bin 91714 -> 91990 bytes components/esp8266/lib/libcore_dbg.a | Bin 92978 -> 93258 bytes components/esp8266/lib/libnet80211.a | Bin 392468 -> 394484 bytes components/esp8266/lib/libnet80211_dbg.a | Bin 431856 -> 433872 bytes components/esp8266/lib/libpp.a | Bin 262952 -> 264384 bytes components/esp8266/lib/libpp_dbg.a | Bin 283308 -> 284852 bytes 7 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index 9a90de1b1..045ca0221 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -1,7 +1,7 @@ gwen: - core: e2b9f8c - net80211: 3a13410 - pp: 5e3fa03 + core: 02023b5 + net80211: 02023b5 + pp: 02023b5 wpa: 27927af espnow: 27927af wps: 27927af diff --git a/components/esp8266/lib/libcore.a b/components/esp8266/lib/libcore.a index 43954e44b7faaf29aa8674acbe406965890930cb..7c0c2c4509482c92eb270fa6479fd036777611da 100755 GIT binary patch delta 13315 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 delta 13138 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 diff --git a/components/esp8266/lib/libcore_dbg.a b/components/esp8266/lib/libcore_dbg.a index f978edc1430cf1efa565b0962fd59a11c56e7721..54a409dd9dab90bb7504970df3ac8b7d3bf525bb 100755 GIT binary patch delta 13538 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 delta 13773 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 i+}n=A_)9AW5U%*Qx(JjXa{% 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 L(ttzk>PP<*tONsh diff --git a/components/esp8266/lib/libnet80211_dbg.a b/components/esp8266/lib/libnet80211_dbg.a index bc4e4f3789bdfe6e7cb68f7566b1c59d53f0f727..c1632a74f1fe4ac329b446fbc279d694c1c84501 100644 GIT binary patch delta 28299 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 delta 19112 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 delta 23604 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 From fbed87bb5bfee4118dff7fdc31b75340542cb6bc Mon Sep 17 00:00:00 2001 From: yuanjm Date: Fri, 27 Mar 2020 14:23:14 +0800 Subject: [PATCH 39/89] feat(tls): update esp-tls and tcp_transport from idf Commit ID:88bf21b2 --- components/esp-tls/Kconfig | 18 +- components/esp-tls/esp_tls.c | 60 ++- components/esp-tls/esp_tls.h | 139 +++--- components/esp-tls/esp_tls_mbedtls.c | 29 +- components/esp-tls/esp_tls_wolfssl.c | 395 ++++++++++++++++-- .../esp-tls/private_include/esp_tls_wolfssl.h | 14 + .../esp_http_client/lib/include/http_utils.h | 8 +- .../tcp_transport/include/esp_transport.h | 12 +- .../tcp_transport/include/esp_transport_ssl.h | 20 + .../tcp_transport/include/esp_transport_ws.h | 37 +- .../esp_transport_utils.h | 13 +- components/tcp_transport/test/CMakeLists.txt | 8 +- components/tcp_transport/transport_ssl.c | 29 +- components/tcp_transport/transport_tcp.c | 16 +- components/tcp_transport/transport_utils.c | 6 +- components/tcp_transport/transport_ws.c | 185 ++++++-- 16 files changed, 804 insertions(+), 185 deletions(-) rename components/tcp_transport/{include => private_include}/esp_transport_utils.h (67%) 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..da4dfe291 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; + } } } @@ -240,8 +249,8 @@ static int esp_tls_low_level_conn(const char *hostname, int hostlen, int port, c return -1; } if (!cfg) { - tls->_read = tcp_read; - tls->_write = tcp_write; + tls->read = tcp_read; + tls->write = tcp_write; ESP_LOGD(TAG, "non-tls connection established"); return 1; } @@ -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; } @@ -286,8 +295,8 @@ static int esp_tls_low_level_conn(const char *hostname, int hostlen, int port, c tls->conn_state = ESP_TLS_FAIL; return -1; } - tls->_read = _esp_tls_read; - tls->_write = _esp_tls_write; + tls->read = _esp_tls_read; + tls->write = _esp_tls_write; tls->conn_state = ESP_TLS_HANDSHAKE; /* falls through */ case ESP_TLS_HANDSHAKE: @@ -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 7e9e0b516..a5983b2e3 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,46 +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 { - 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. */ - - esp_tls_conn_state_t conn_state; /*!< ESP-TLS Connection state */ - - fd_set rset; /*!< read file descriptors */ - - fd_set wset; /*!< write file descriptors */ - - bool is_tls; /*!< indicates connection type (TLS or NON-TLS) */ - - esp_tls_role_t role; /*!< esp-tls role - - ESP_TLS_CLIENT - - ESP_TLS_SERVER */ - - esp_tls_error_handle_t error_handle; /*!< handle to error descriptor */ - #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. */ @@ -304,6 +295,28 @@ typedef struct esp_tls { void *priv_ctx; 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. */ + + esp_tls_conn_state_t conn_state; /*!< ESP-TLS Connection state */ + + fd_set rset; /*!< read file descriptors */ + + fd_set wset; /*!< write file descriptors */ + + bool is_tls; /*!< indicates connection type (TLS or NON-TLS) */ + + esp_tls_role_t role; /*!< esp-tls role + - ESP_TLS_CLIENT + - ESP_TLS_SERVER */ + + esp_tls_error_handle_t error_handle; /*!< handle to error descriptor */ + } esp_tls_t; @@ -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,30 +427,30 @@ 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) { - return tls->_write(tls, (char *)data, datalen); + return tls->write(tls, (char *)data, datalen); } /** * @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 @@ -449,16 +462,16 @@ static inline ssize_t esp_tls_conn_write(esp_tls_t *tls, const void *data, size_ */ static inline ssize_t esp_tls_conn_read(esp_tls_t *tls, void *data, size_t datalen) { - return tls->_read(tls, (char *)data, datalen); + return tls->read(tls, (char *)data, datalen); } /** * @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 702d2b81e..245921fd0 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..7c99830c4 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,205 @@ 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) { + 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); } -#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 +330,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 +369,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 +381,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 +409,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 +498,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_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/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; +} + + From 8925ac5480411bf4b88eba3358428e1db559f493 Mon Sep 17 00:00:00 2001 From: yuanjm Date: Tue, 31 Mar 2020 11:42:11 +0800 Subject: [PATCH 40/89] feat(tls): Modify tls component for building --- components/esp-tls/esp_tls.c | 8 ++++---- components/esp-tls/esp_tls.h | 8 ++++---- components/esp-tls/esp_tls_mbedtls.c | 4 ++-- components/esp-tls/esp_tls_wolfssl.c | 6 ++++-- components/lwip/lwip/src/include/posix/sys/socket.h | 3 ++- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/components/esp-tls/esp_tls.c b/components/esp-tls/esp_tls.c index da4dfe291..8aa5afe5a 100644 --- a/components/esp-tls/esp_tls.c +++ b/components/esp-tls/esp_tls.c @@ -249,8 +249,8 @@ static int esp_tls_low_level_conn(const char *hostname, int hostlen, int port, c return -1; } if (!cfg) { - tls->read = tcp_read; - tls->write = tcp_write; + tls->_read = tcp_read; + tls->_write = tcp_write; ESP_LOGD(TAG, "non-tls connection established"); return 1; } @@ -295,8 +295,8 @@ static int esp_tls_low_level_conn(const char *hostname, int hostlen, int port, c tls->conn_state = ESP_TLS_FAIL; return -1; } - tls->read = _esp_tls_read; - tls->write = _esp_tls_write; + tls->_read = _esp_tls_read; + tls->_write = _esp_tls_write; tls->conn_state = ESP_TLS_HANDSHAKE; /* falls through */ case ESP_TLS_HANDSHAKE: diff --git a/components/esp-tls/esp_tls.h b/components/esp-tls/esp_tls.h index a5983b2e3..9f2267b47 100644 --- a/components/esp-tls/esp_tls.h +++ b/components/esp-tls/esp_tls.h @@ -297,10 +297,10 @@ typedef struct esp_tls { #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 + 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 + ssize_t (*_write)(struct esp_tls *tls, const char *data, size_t datalen); /*!< Callback function for writing data to TLS/SSL connection. */ esp_tls_conn_state_t conn_state; /*!< ESP-TLS Connection state */ @@ -442,7 +442,7 @@ int esp_tls_conn_http_new_async(const char *url, const esp_tls_cfg_t *cfg, esp_t */ static inline ssize_t esp_tls_conn_write(esp_tls_t *tls, const void *data, size_t datalen) { - return tls->write(tls, (char *)data, datalen); + return tls->_write(tls, (char *)data, datalen); } /** @@ -462,7 +462,7 @@ static inline ssize_t esp_tls_conn_write(esp_tls_t *tls, const void *data, size_ */ static inline ssize_t esp_tls_conn_read(esp_tls_t *tls, void *data, size_t datalen) { - return tls->read(tls, (char *)data, datalen); + return tls->_read(tls, (char *)data, datalen); } /** diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index 245921fd0..52c9daabd 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -489,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 7c99830c4..08ea8b5d0 100644 --- a/components/esp-tls/esp_tls_wolfssl.c +++ b/components/esp-tls/esp_tls_wolfssl.c @@ -231,6 +231,7 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls } if (!cfg->skip_common_name) { +#ifdef HAVE_SNI char *use_host = NULL; if (cfg->common_name != NULL) { use_host = strdup(cfg->common_name); @@ -248,6 +249,7 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls return ESP_ERR_WOLFSSL_SSL_SET_HOSTNAME_FAILED; } free(use_host); +#endif /* HAVE_SNI */ } if (cfg->alpn_protos) { @@ -438,8 +440,8 @@ int esp_wolfssl_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp tls->conn_state = ESP_TLS_FAIL; return -1; } - tls->read = esp_wolfssl_read; - tls->write = esp_wolfssl_write; + 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) { 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 From b5e916c7ad38dff7e8b1b793ee12b0d087d3cbb0 Mon Sep 17 00:00:00 2001 From: Zhang Jun Hao Date: Wed, 1 Apr 2020 11:32:00 +0800 Subject: [PATCH 41/89] fix(lib): fix memleak when station send illegal packet --- components/esp8266/lib/VERSION | 14 +++++++------- components/esp8266/lib/libcore.a | Bin 91990 -> 91990 bytes components/esp8266/lib/libcore_dbg.a | Bin 93258 -> 93258 bytes components/esp8266/lib/libespnow.a | Bin 36796 -> 36796 bytes components/esp8266/lib/libespnow_dbg.a | Bin 36796 -> 36796 bytes components/esp8266/lib/libnet80211.a | Bin 394484 -> 394340 bytes components/esp8266/lib/libnet80211_dbg.a | Bin 433872 -> 433720 bytes components/esp8266/lib/libpp.a | Bin 264384 -> 264384 bytes components/esp8266/lib/libpp_dbg.a | Bin 284852 -> 284852 bytes components/esp8266/lib/libwpa.a | Bin 135502 -> 135514 bytes components/esp8266/lib/libwpa2.a | Bin 25108 -> 25108 bytes components/esp8266/lib/libwpa2_dbg.a | Bin 29460 -> 29460 bytes components/esp8266/lib/libwpa_dbg.a | Bin 185218 -> 185230 bytes components/esp8266/lib/libwps.a | Bin 51080 -> 51080 bytes components/esp8266/lib/libwps_dbg.a | Bin 67536 -> 67536 bytes 15 files changed, 7 insertions(+), 7 deletions(-) diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index 045ca0221..8fe12d675 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -1,11 +1,11 @@ gwen: - core: 02023b5 - net80211: 02023b5 - pp: 02023b5 - wpa: 27927af - espnow: 27927af - wps: 27927af - wpa2: 27927af + core: 7743eff5 + net80211: 7743eff5 + pp: 7743eff5 + wpa: 7743eff5 + espnow: 7743eff5 + wps: 7743eff5 + wpa2: 7743eff5 smartconfig: 2.8.2 phy: 1156.0 diff --git a/components/esp8266/lib/libcore.a b/components/esp8266/lib/libcore.a index 7c0c2c4509482c92eb270fa6479fd036777611da..76652953776d992227f98c0e78d16794639b451e 100755 GIT binary patch delta 142 zcmcb1j`i9()(JAK<_4A)78?~gc_6IK`aIf9P-Z;ebA1SNvObT*=489$A}~e4?fg)g tcs_~Emy`Ch!WD{dUYBtLYQ$ua?BeXn>~L9$&B4X|_YmCe^?{7nMFD75DNX~L9$&B4X|_YmCe^?{7nMFBiAD7XLs diff --git a/components/esp8266/lib/libcore_dbg.a b/components/esp8266/lib/libcore_dbg.a index 54a409dd9dab90bb7504970df3ac8b7d3bf525bb..ed0ef22f0257e8aefc27deded9ac799f1ddc1c3e 100755 GIT binary patch delta 140 zcmX?ggZ0!6)(J9f<_4CQh9(=8IC!AU%?3PLOfYr=-!pwEd$IwK_~vB0<03FQgJ3OT n7&{^D8Y@Db*yf;|8*noW@>j9L)IBIGyN^&OzP&h%@wzAgqk$)z delta 140 zcmX?ggZ0!6)(J9frp88wmZlq(IC!AU%?3PLOfYr=-!pwEd$IwK_~vB0<03FQgJ3OT n7&{^D8Y@Db*yf;|8*noW@>j9L)IBIGyN^&OzP&h%@wzAgl}pa delta 78 zcmdlppJ~s0rU_CU<|gK*#)f8Q8}paqs@lF-8KMAVinB* diff --git a/components/esp8266/lib/libespnow_dbg.a b/components/esp8266/lib/libespnow_dbg.a index 5d657c3335a09a2ed710e9555bafe2e020cd6b64..e579ea0ecebe38979d2da6f9ebc14b0fdd22d344 100644 GIT binary patch delta 78 zcmdlppJ~s0rU_CU7N+I~mX?O58}pa}paqs@lF-8KMAYZc7^ diff --git a/components/esp8266/lib/libnet80211.a b/components/esp8266/lib/libnet80211.a index d01c00ab313f01ab6cd659afbe0a87462e1cbcb8..d09fe41866487c8f1bc26747d78530c89f7510d0 100644 GIT binary patch delta 27923 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 diff --git a/components/esp8266/lib/libnet80211_dbg.a b/components/esp8266/lib/libnet80211_dbg.a index c1632a74f1fe4ac329b446fbc279d694c1c84501..f5c6eb0f438fffc605f00c8d68d986ba73cf151e 100644 GIT binary patch delta 26278 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 delta 167 zcmX>wQQ*KtfeA8frp88w7G@ij^hBY|>HGK@#Wv@NR%jy&Y;sgFMB-hmN6DQL=oB3&SWD3)9`OL)43uP=@)#=H+}*DrPVSh diff --git a/components/esp8266/lib/libpp_dbg.a b/components/esp8266/lib/libpp_dbg.a index 382878b6bbbc0c1095477698fe8e5ac4b6354dad..7d35f02ac5f8dad09b8b0ea2ec703f0a0aa6d00e 100644 GIT binary patch delta 170 zcmdn8QEK<_4CQ#>N|!^hBY|>2c>7#Wv@NR%jy&EOIo5apfK{iEoyzXr2WV z0BR85zE_CxIunwJ*!B&gj4O6RMYaRgT>66|?Q@3d49w2$Kr{17k)*}jSB5ihUm4EA G%?JQ*7d0CI delta 170 zcmdn8QEKrp87_hNc^p^hBY|>2c>7#Wv@NR%jy&EOIo5apfK{iEoyzXr2WV z0BR85zE_CxIunwJ*!B&gj4O6RMYaRgT>66|?Q@3d49w2$Kr{17k)*}jSB5ihUm4EA G%?JQNr8JoU diff --git a/components/esp8266/lib/libwpa.a b/components/esp8266/lib/libwpa.a index ca2b0ff5a85d036b57826030e18e4473fef2d18d..23a911b71a17846ea6adf3afc0d515b2527e9f72 100644 GIT binary patch delta 3139 zcma)8ZBSI#89wh_Sa-XttYovG*sy!Wy?llRHNYt4qqdfmh^84$Mp`sBXj7)pglaRT zT@n*BlhT3q$Xu+Q$(A}vra@6RGn?sP5Nr*jw9wczriAdJd`v@)r9YBs+H9Y9IiQ)Q z)0~;-d7tx~_ndp~J(^{4 zgK!5=rexD7n-}whsLffo=IP=Dz0XB&v*&y|e<)e+^U_<3J(u2>euTtV{#a~{rM)3r zwyzEj@^Id{sADcL7}B%r`+B0Dv!XooyYrj9bdd+|bKV~saDGt_h3EqJf3Nw@M!h#e z{oiTm=_(I}oR%CXo#T<(9JlXeH1AYYuk-u5qWN{}^t!Z*al-d<)L;BLyws?x_Ve++ zmw0@>T4=r`XL#L?w7Y_3LI@3b2H<7`SSJEHU;^COXYB>pj{pR)|0<9H@H!I!H}+Y7 z3E+G`lFOAoz!TAsV+ii7M2C}}fVL>z1ieb>b~0%>`NMZMJZS`zzuwpsSU3LO-&g{epMKyXHmR7&xeOGW0%x z{b%H+4kP%S>Meda+6@Ek7{FOxr5(!WS7M)ECk>!#5ZWn#efC&8l+StWPaviPv;&0J z55V6RGr8kX1KH4vNy7_Cf<4xYIf2`9`1|n#*qfEP$C82;^|Bk_uy%YM0xe1Te9ndF zQ&r3sUgfjL+M)c-ob!!^oPf$?N#1~>S?o|V9vUWTWv&DAh^XYtB zY5q+;u5?q_^7CJnQHy+Wq>8>NKLCg1)_1C?O`70pIRic|3r4f3UG5uQOL6kqQG>3_ zZt!XO7C22t!7gdMYfz=Eit!<^S3VEkBVPxH%pg`32u_T;1hBNY?BF- zyiNhQS=NAC1;D5BBx&OuOicOr18!A-95OW&O0FS$wi%+K+X5rwwZ`Ux;42*=!}9 zN@c=~VQt=m)3%tU1LX1S{a)jNnr}UFcYUtco40YXlEzBIk7f?0exeXW5|>fA_mkFR z2EDd_$>J)L9NFGV-(SDvMc^HcU+VJGk*5aeWA~C3t4&%UVD4z83~Gp69wmczrHS-y z&ecEDGxctof14gouwOcsd5=>IWFGc<8wVeD)b7bV?3ou%i~dVTew97*Sbl{#q6zdm zxz|}C^aOjwceC_|_CE0>jqnYRMa;4>atGh!9)|V)hVjYJhbwlD#g|=D%AJ5%a1sCcW^ewEA zUWV1@QE0js3QYp_@PIG#Ow^yV(g!Yf=-nTw!h*t6?@t-jLv4jS`fE@EGjr)oaPcbX~ll)90(auDG3X2c&V&0FV+Kp7yk7XZ#-?*+4do|1z7%1TCL?Z^b7T>&_C z1D>`9nzGmxVjN(fJ=PB8d!b3q{ScaS*kir8rbF$Vzg8N2N)tf@A?{EEY_fK+KuZS} zAFQh!_E;}Im_HRitO1dagP71ZDWAKn9m?OLd_JaoDR*HqcVaac3-Or+Fo|+_86h53 z6WDt+68;AzIjPdT9HlC1YERJ)QCGXvvgmMoueO$E+plQ`HJT1WSYxi|aKhZpq0&6e zVa|M+Lzj7l!vXUn4!tXU rdJ*MySc~0p%R8L-J;mXlLJa%NZVXehc{xtYSh{awS5RWSw%Pd~FLlF& delta 3305 zcma)9eNa@_6~E`f0=hf02tou4yAQ%+`G_EXKm+B&)MzylDU;GdE0PwR2@^=gsSQrH z2KzPA5p&U(RHxah)20m-n|0hyKMY`MoCtwbGjTK<5c!bev=;wprcS&4o#if4n@)3P z&hPy0@0@$zefRBqXZG6hsCSP?btXowTfJ^geqKT0A^q3xtwK!ww^PKJ_*8C`3;KV4 zFj>(5@`g`J^q&>PezEet`=1r`DO?L56QAI+Bs#%6M1>La_wKbv)!sh|v*jWscn|2` zjh`=&_NaL8BZa5#PciEZ6x}N+TePq!!CSNGeQlu;UdD7ewv+nSWWs(gAwl-T=*BgfvbbWuj%(SFDmB1KLZjd5AOb}MNB z(o=&%A0YaOwF`MdG~_(IVt;Y8-e;$4tl9Rj8hS|YbI{e$$gcNge2>J&_kvX#U6!3s zCb|bXop&x^y`4MY(X*TT{t$?NLzH{|*jwbFw>kNQtu2CDxCZyb*;r@( zc{tbWC@xq0>pT&LnsmW~7!0^*H+Y!hd%%|~e#rdk1SQFq44Zd(%Ra;Hh90*_h?9ti z6z5HxR=f>!uPHu`Xu+84+3bpkgRfqoS18UKuTH9#5Wax z2>fX{>o3ZZmksy#)ril|0jC-O>lIWd?*Wg=%^y}!hdc_bmNUR^`KUjO4#`G;DhYYO zZ)l_8W?dS^%Xj>CWUu=Ta>%fc46?~A;70kyAhrQl$P>U?c?oz--UWusq!EK|%k{u< z`3&$iDS_egcO!;oTXf`YEc}lVJK3dm)Sxbz53G_kz$>zS)X+X$Y?fLmK4xX45aGCA zzGt>Bc^TPTi_P9tWVb$$^~ls4yq(R!TXGk$TOI}Ok>`OPIRgxrv15j-3hy7k3L)cb zu)Y7lihJeLV+M}y0B~G-fw}TJ@GTj3)4%~{0dW*J4cEtUIPuUjSSdtb#oM*;4m#zD zn})V?xp^9g8*}!7Y?r(nTsLXlpx?;#z%%k0;4LY~4OeNR5MKx_yx5$e51CKW!cvaQ_hh_VOp>?J3@yEP?N&M#X*M|*98%&y=IQXR|vN(%*8%mMG>*D2S zC+!p|H&60u?3y&RfI}XeOvgpeLu!*Vz#Uf-tp~y{pX)!;EGE=A;;ZQ!AvRt1hXBdG5Lk5!yMZfsb`_xc2-M$+THq1zN~+4MuGaTXyY z;=79Tk9$nm;fg)|gw>_4%myT72;QpeS2>1wn{>m0*#%l?kj!>HGxC z7x2xB^V8%$NjbrCQLl8?>V0qCr34#2W_}Q$3Ti!UXy2lfhhNpQsO|72EtN(O|5Y=n z$xI-GIJ1PqF|(1wW9C5)f*&;VRG4O`CFYx~ZHO>S(<$Ek7i+y{bU4a?X0GG#q`4g- z;v7DI!nT AJOBUy diff --git a/components/esp8266/lib/libwpa2.a b/components/esp8266/lib/libwpa2.a index 23947f6899f5ace7f947b15ed2543491ad3f1d64..f5aa055b8463043a71f3dd99301d15182450d3e6 100644 GIT binary patch delta 42 rcmbPogmKCd#tBj!7N+I~mX?Nw8TTm diff --git a/components/esp8266/lib/libwpa2_dbg.a b/components/esp8266/lib/libwpa2_dbg.a index 82ffdcca03115706880ff09fba1c9f15ac0dff36..5ca77470aca0e395f0f1dec1050892b995beb1ac 100644 GIT binary patch delta 42 qcmbR8jB&~{#tBj!7N+I~mX;=l8GpiPm!;FD z)7+VJf8Y7;xo_`%Z};8pIB5LnpwT@ixqRUwPenyp#ZSzmz8ylkza$#g3HeoG`>%xj zKcN=6#s7@vFB@z>D-@!mc`Dx8A=FoiGp11g9sa*sZNc-hA}PN2pf!0kC!YDO$r-^J z`MWaW4tdTfTd=q4t|e{-k1T6QnaZrIKUMJz7f4*_E%A8$srmWx$za{uJu`hd)t+5SPtxb6_MYJEY7h9WW&v5nc3$vM&EJSgF97ib^hE;Ob z2-_n+%PNu|!Q53Mnv3UWzfhHG_FLtLuq-c>p3gM+*l|S80tkt0Kj>+i(0Q($peI4+vb1J7uk z$$Aq9{1^QTPUrh}>nwVwSj)}aar-F;s_a@D+Q*jQV>@{qvV}Wty&Ul2K^xjf9sF^o zi$gYX$1TjkzB_6nF`BsJR>Uz`bb&P{!@J;*oVNLJx8Qh~(37*gtmPK&xFzV#!h<%n zZ__@WbUBa7Z=;&GsC{_QhW0Btm)}PPe_pI+qkxIT&;vDkG9GC)k4fBKZp*Y^t+k>3 zmDF(=xi1kL*&gTO9>7}7Zn1p&??|CZ3nK<0icb}0qt}LsH7~DQAA6C z0JQ)o$q!W1380*=F$(%@u|33=IHm6<^Sx&?Ne>KCSuW3-p!Gl_bpk7>hoM%_p(AT# z2HnV&R{qR;7;2*2JVrS!2d>jLAe;69V>AH#jcx)KN}C@YTMTs3CcsWF$Fd;crK><2 zB{&&Js1Ue7s{k);2fFA0kV)r&BXkGoqpW;h-v>n$2&)WQm(T0FPA%-oe~=$YrxQRI zT?0NK!^Oy>GN6yv0~6EG;~S&o^v%=;;Dk z*nFYNZU%(>9mcrW47ZN`F)%T6&Buu~#<|FfKgCYM^Arduo9`^DjG}^?v7&%!ZvE_Z z+KU!{l9cnqG=7#JCRnl}>AIg7MElKpf%0uaiLhNJyUTeIcZfIS~(~~(+13&sY zW{qXlY2U&+dSbGVZLQ`&{W|7at+9n?wBE`5VNCm?d&UVW@&AF_I~D zj$4=mHSnMf?O)Qqmlu}JS{8E0ZHxo;@SqLt+eO{fMJIHToe4d8QA6(%H$IPjiH=*E z_K~Jh?{WSDn%Z))1wHvWxQY0DJQqAiiH_T1?IVRYwEs=*v=$g89}u8}fQQZlne;huoaPNNMyU=Mp{)!h zvT5&-a>_C~jr6G`yd3GDL%fuCD0P?%Z_y$Ke>tgXm#QOmyo^WnR` delta 3346 zcma);4@}hO8OPuE<&L5!lVm6kTjrYUN>YqzmsSBy?g zucf548=KN=_AF_mzqKZ`3lrOGb4}~`b1EzyPMVr%TAkF{SfWv9n&@iW?fD)rv}9e@ zCwbn__x--l`~LnN@5^s{jgDSp@BGxtipnMa#pRVf=9|HtLY90(Hm?)%+vKkIg#16L zDvQPc%)mDd?j8{e*|FuT+_zJxZsb}(LdLetNBRt3T zoMX0gu;xqKj1xYzrumMqdiIAdtC=3=CoQQc_xVC;E|+{X+_3(oxxt(|U%Pj1>5-+M z%1f~!A*wzd8fwq+FRq_lnJRX_<@DME8F#pcUyiapk|Mkb@;u6->hqj2w$>dN=9rX! zhc{9#M8LZ+x3ebA9Jb4k;n_MDpU5_co$~Z_&u$L8pOa$Mhw&;UKMHLM%nu&NaQQ&Y zxa=FV%(AxOKgS$ziF)hUP_m&ll2$da?`TpQS^_if^f`v#ftuX>*2n7%d#bS zZE^r30dHo(!B}~J%xo<#_)~0g>q4`&Xe3b-^u>y6=I}F}wFed?6}*A*>l=kC$g+k1 z6&P~|?-4>M&JIpQDkpRXr^)#eCjvfnJ}3Mzr{skHHm8SEah~Nwz=vMJiF%WZ>$QFq z6FIoXCD2Ld4vMz1PSAP>>$|k>k+iHz&JSHHvxR&1-u4EAJdim@hy%aa`2$1YbsFF$_+=16E*Ol4eigs!z%{xGq*B(x_*gANb(%DuD;@OILTQ(|vI2frMbD@>8A-N*ROSR{b6chj~~1XXr+EsOjMA)kSngBVuE5*UZ`%hgYNOL zl|zjlu6~fV1G%&x*hQnjX}ZctPFW+wI|dDnD3h;ITf){E{#6$wkbP9$nbop+Tl?cJ zKmO5o+ZH*Uf^ZW0PpMHBIpX^f&GH43-TH9UM%@VU;Zb_Rgx!b0Eo@brT_77^u znvB3E&$HdvZONu}X-nf|N#T}y!AF;Pv2pUn<(JH~$<ik1f$V_a-Tw@#e5Zq8kIE@|2E*u9_OEL&m84>5dOdFCdk3!a|S z>X9|yu_-wQ-zf7en<%qPv+bY5vF=yvtqs@s4`>8K_oZ!&FJZ|ebj4EHzWCY4XJWB8 z9c_(a_TSP+-JzJ-R-7|tT6?P=h_>*dT(U@pX-`PzMwxZ!w@6E*Ol4ekF` z``E~HS<6yxI8F-@j8A~c9bxDJC+q1&ud&9W@Svv`P0-JR*IUHCM8jcdA6;le`)=+} zUwFQ*ar5;BI@1@%%frR+J@EY`8VbLP;WkePK%Rw8WYCG?OA4OFuZ!xi`D&$?N@Q8A$ZbkN2lq3BEo|eed>o^e> zJ;}qo>%0t%(-9z%E&)E8ca-roeGhQbBfv@eHSl{118({Ruv5Y@Mjw>|C+R_kI+{dQ zzI0@~pk`n4W)2-VrixW*GB(MK*Lj#v)0qe)hwiU-(3}xvm-{GZgctmrmNV49lc{w? e74x|jg6p97rw0E4JWs}`^32+0xVQOw*X=!M0xZeng~Y-nk)QHg~G&e^QTBIzt+VacFZl%JAVlBgFS?-uIk9OCKk R7ay-;VPS5$IoVyc0RU|Y5}yD7 diff --git a/components/esp8266/lib/libwps_dbg.a b/components/esp8266/lib/libwps_dbg.a index e1fbde878ee9e1da48ffea292aab684ae94cbbb8..21067316eb8eaeb5d04eb609e332f4883dbc60d6 100644 GIT binary patch delta 219 zcmcc6&vK!kWr7rkg{irLrKO3%MkN*&IA^mSOI)P5F@s)FeoA6VqF#J_T4`Q#e7uUK zp_$oa!8l=N3sX}Nt#4ssiA|NE0TxjMQwyLT5hhb(ASKEOGDt+k*pxvpskm6Lyr4Kf zsWeT+!qU(HBq3vHj%0*esGoC)r@tT22^N+HAO%1tSeQd-a}x+{Y`Xbi9RErHRk=M4 delta 218 zcmcc6&vK!kWr7rkxrw={v5}$WMkN*&IA^mSOI)P55rbY)eoA6VqF#J_T4`Q#e7uUK zp_%Dq!8l=N3sVyit#4ssflZZxB^FTwQ*)pm5hhb3ASKEOGDt+k*n~kZskm6Lyr4Kf zsWeT+!qUJJBq3vHhGc|WsGoC)r@tT22^JQXAO%1tSeSumCJXb)0&ybD7RDx<561DY F1OOLaJmvrZ From 6d1b499b1ebfec93a520e89b0ea344d64bd957d9 Mon Sep 17 00:00:00 2001 From: Chen Wen Date: Wed, 8 Apr 2020 17:58:37 +0800 Subject: [PATCH 42/89] fix(wpa2_ent): fix the issue of disable wpa2_enter --- components/esp8266/lib/VERSION | 2 +- components/esp8266/lib/libwpa2.a | Bin 25108 -> 25228 bytes components/esp8266/lib/libwpa2_dbg.a | Bin 29460 -> 29580 bytes 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index 8fe12d675..89a8302c4 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -5,7 +5,7 @@ gwen: wpa: 7743eff5 espnow: 7743eff5 wps: 7743eff5 - wpa2: 7743eff5 + wpa2: 9a2e4686 smartconfig: 2.8.2 phy: 1156.0 diff --git a/components/esp8266/lib/libwpa2.a b/components/esp8266/lib/libwpa2.a index f5aa055b8463043a71f3dd99301d15182450d3e6..e36eead2857bacd2b6078cc1f9f5460ee5ad1f4a 100644 GIT binary patch delta 1154 zcmY+CTSydP6vyYx?&{jEVJA$i2MZ!))K+7l(3rg;Z`4hOR$?>qxPtiUVB ztAcj7ueQ}$`Q37_sOi3Lbmh=5t6$TM?d^*%Q{YiXwmBn(Ha_VaBR$#TUqV!#?3&V$nJC9F3Tv9w^^gvo5D#)f9nf^hfUZC` zNc^ji2a^7KkPnicVaTO;6jj#6e*@;<>126wgAvl;%Wg z-@R%<9(-T1>`~4t8caEIc*MZNf4RaX?spD#VE-)!OXT#g2ND zzHt<}h_BY0`rJbPU0+Ryc~yf+VLpfajVBsR-Cx9Ijn%j~-e^(}zec{u^ER3EmiHo8 z@!%#?*OqdishaL^OOr`I`EJuf8t0Eqxfy#_XJAG#+wn!+Sl;@p!J|^g5xAcrICd6YE9%I+g#%r~U&G#NJ0NP0;tNHC~}$e>4KI%mBv9r&OB@BZh`ow;|W_Z7Q4 z$NKX&RqQXTtn@x}IxHNa+L9ygEr(`{TO4gNx-D0>cB(ULOPQO!Z=H+3O~>xs*% zzc;n!mnk1^8XnOeE9{S%5QJ(`i^a7;=6ESNf0#uUYBuM0v#5aDK5Uwn>8}-JF}_7e zh=QZmtXVa^tEQ~7Z?wR%G(q#kdxyLq&D!Bk z=Xp@F@{Hm9MXOYX(F5apQD7&0^|f_Y;?S;Q!#a*4PC-A*nVxW-vy2|&te{`!Y)8M! zIUBv3a{~P~=k4fyoOhw$-{4MR8ewo_kbE$0fnI_ZI>?!}c!YBTy%5DtV8d!c(R|8? ztvrwLJb~W9nU1iBa~HZ>2;f3=1XzHgh1{I2Jb%PC9GyVR7Rf?>l`ud73&gl&IY#==fa)zV&jSbgN3z2#~Gc? z!2)&}@&mfKUIG^a4J-�iC5lMvyLtg1Wd?3QvO#IQWavO{fp)>>518{sMktcSCiH zE`F|pzLo~o4_{hz_6|JZVm1#mejBufl}(LD1>p^Y?yx46=W#6b>UIex4N=rmmplEzm^x{{tw{b B;GF;f diff --git a/components/esp8266/lib/libwpa2_dbg.a b/components/esp8266/lib/libwpa2_dbg.a index 5ca77470aca0e395f0f1dec1050892b995beb1ac..9b7d7ed2b77d344c1305a03865eae25e05e7f17d 100644 GIT binary patch delta 1362 zcmY+DZ)j6j7{$=|j5i9W`kCu9J9ZIR-%_rYh zJka(pZfUGue_@X~w*8Y^um9RtZO^%T=iFBxx$X0AY~G#P$AKn#?2apSbIuJv@P6Gm z6bS7c@U{Qw1~zq$TyRd8Q$f0&)KJqI3V&7-n|0S}2|)>tgeLnt*KsPobS8tZDK)ND zc%vsa<+jhbfgs(N(HqJp11L;6jYGp{W4GOnBcIT;bObaew!cDg;Z8+&#jrzu1teqtg+h?LQ-Ohg!;8VvFa8p6S&=Q(KzydQCLgW)-S3qmX7aVG-i?;52T~26 z*mXVk2Cy<%T&mBo975VKlFAzPARjbbj(o^)CGvZQUqY5G%AAXlPZ?f{e8q4b@>r2` z3df^vn2tu|al@;SCk(GfzGGPSI%8NCyKlG^dET&`!5@Z~B3pQtf@I%vZo)EWugVo4 zq~a7L9l~u8twlgP3W?ul*l+w{EC45sY}XlEfAE1t05_?L~pB!>aF&4b*4 zdxm9~9pL9hd~ba5gr67j#Q1VEUV%ui8QL>Q78Xy~Z+xHGy_~`h_)S!bh~_sPVha1= z%VJf=mxAQG5piN&B>(2_f}euCb^luw;`94gwpOAK?V=B_go}JlxT?sX3(Mz1n-Z3* zjy9X8KFdRg+1sC_Tl{)|QkOUL`Tm4ftNG9V1nuE1sigMB`NLEKFFZ^o=_$ttlGMw` z5F2?Kag<*^kfdMvAmSdLIFQtpn>n180dJ?1+S9>f>E+bGKcpkx?k=SYT$+i{4qlOo z>b70HGqa3(`29?j?(sRqQ+y{A^I`zcPLzOHNthY#}zb&52jDK+Lk3eH|Br0Glu;_ zEeZvVsp20U+kU2k#=i$j?OC;dR_%JKn&wn!PK_QQt47YNQ6X;6D&L>xSXI*Uw5JN1 zW|Y;kd+4%rp-7@lhz7%nCY>*&?^n})sMfi-cdR0@H4ptFCpokKQkLa7p0Q~1re_>)Rax#(`ci47l%DkM zm0P6TnYLCB6(n{FA!JYp_Aq2XC!y_-15H4t<_w&N8)9A#anB6IgLCF$h}ZcC@ zmO>P2_JVn!KfR^guuR_kX1b~RSb)Yq97(*7X^AJdUYBMI-mMuXj%dzQA0W136g z1DaRB`I~sn)$p^L%i!N=E{9*qaY6(ESM`JS@SinT!>?{L z^U*V>xeU&i!w2GZIyCbk4~azX0Z-~7S%-pg9O4%^V=mPBCpzbwPif`@HG<_16pYUx zez#F`q0Yb7IrsmjIfMO0R!=72+o0EnxUX~0m|q{_iO%_}-h*Tq1>+^e8*|27sB?i0 zIp_7uA&EJUGAMmzpR}ZxemLAEOUTpxcF4z%gcx?Ck$*ajpP2c6F~*robDU*fN&8DS zq=&n+F4;jRdLr^G%Jf8x=QZ?JZ<{f_k@|YuWIbK$jTkevv?SVwhR$e2X6akhM*1Js zO|5+qnWE28C+G!gJvH=4jQJKi)6XwFz~s?(+7PS6S@*{LX6*+;T%eONzuZh0V*%q% zJKc&^nA>pTt#qT?OV-gM`4O!-8ZZ;c*3jc4Ug|(LNKs^i$nqBYh8MDHZ)E>1WQ*eg zbca#zQfEA1F2xOey0Fe*yvTUIm%fWvn3oYw(^TAVX7@440l)m1)(!;Z2(=CbR@|u) O;&fi_y144A7q0*)dJ8ZB From 6dc2eee6182a36b565288821ef178d83e3ef2dee Mon Sep 17 00:00:00 2001 From: Zhang Jun Hao Date: Thu, 9 Apr 2020 10:55:27 +0800 Subject: [PATCH 43/89] feat(lib): refactor deep sleep according to ESP32 --- components/esp8266/lib/VERSION | 2 +- components/esp8266/lib/libcore.a | Bin 91990 -> 91842 bytes components/esp8266/lib/libcore_dbg.a | Bin 93258 -> 93106 bytes 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index 89a8302c4..088993b2f 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -1,5 +1,5 @@ gwen: - core: 7743eff5 + core: c15eecf2 net80211: 7743eff5 pp: 7743eff5 wpa: 7743eff5 diff --git a/components/esp8266/lib/libcore.a b/components/esp8266/lib/libcore.a index 76652953776d992227f98c0e78d16794639b451e..df3fff748790cd7755b825dc31b05afbb274b266 100755 GIT binary patch delta 10593 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 delta 10626 zcmai4eSB2Kxt`gO4>-FaY!;SCz+^We0Rn_ifg~6M@);l%Y^kL-Rf>3_y|m_PE>aUq zN)hlvJ=EbAlpv`2DYew4z^z<=(MH6IEta5BXyvD%vKBX_)*dQB+x_lZ5X`0Z-$2i@t#P!T^Z;$CHT_W*YbVePsw{ZPhX6;D)nKcDF3s#KYL`A z^80ibrAYHaeStuq=e4yYPoE>m7;!K^_)=Ejtco38{(ugqeQR|0DQQYg-Q$}&COFhz zkr}I9Q6JEU>~|h|Q2)mM&YE2PlwH53NNm)BKV+Eo+_6lacXUdW(Z>JMn; z#8=%?pI;RBUti^$Rh;Qhsl0I|{IgO<2J3U5*JIg?mlO%s>roWYTwbIZ|5rvDdg-N{HA|2nb;v=^&oG|j;J4(_K z8>Me(PaUDnPmTLiFp}ImFb)i2m^wVFQRmX7`|*0y#jC~h)>Y{olHy)@cFx1^`O^B? zUp~APvsfJPZ?~8J*K37SW+|omR0XV|d3kjsn?Elaa-uIdU7eqDC zw#3u+*+1IQH}>-lPp9d=_TMYRvB~Caiv7l|{y;h6e5mtKyPKEh>8M@#Ou4sT~9llU)7T&|*i_~wynSZat7pp@lU-j>d@CX9D!V$ll#NU$!Bk%>) zzo}2e&$;fUUU5b<88`((P%Tw`I65h8uPBL+X-E>PlK8Dj{H`Q^e-d9SydOFXsvoJX z;OrPf17D{0fphsDboftH!_lM$-UnX{=QCK#psG{8R1hg_sCyF6O5&B^qY?LxGXwXk z+rim|yC>?^Plba!$& z8Xpi84l1Y`8dbs9ga=g>crKiKoPeLH+rhbMhB>@RJs|NIFV_4`^-FL+@F2&(O2xzv z>P-C~g}WWDR;MKX2F5q2ht#E{g!FW#y1Tp=PM8ol*K8STP_0!X#LpPcP*oD2k;LbL zZ$#Yl*sMYIu=;U=zkv;`ND#;$PvS2m@xLVTV@do%5>MsyNn!iB;G7NM28`&JYN`nC zb84%)q=W~-$06aT&K~)ddL+reBZ=<@X9v?zgUYB^gb#4|f2*V5T;jWU{sh%#^$!SM z;Rr7$@lbbnldgv^s2)>=;9T>?4&SOKf_sJe-w@6NGN`txyTLgiE@MzVp?)fS1kazK z+Mym5q1fS1so#Qg3}p^)Q3u3d;qYhFd*EJShh5@#PsW`ph^b_U?j1j;N`?1<7F4^` zEyA7k531+Yy&`a0f@-%~5AGFq@SCss_o!Es{2zYJzfYxEUbeeQhk$cHZu@^wvs^!4 z!)`#G1k{5E)qeHR*Z7O-F>pTDcRBu6^&B_{=FZT|>Sb^i_pv;p-i^iDclo;C^@F8{q~gZu_sRC^=K$TSV+P-Cf&wFrJ|_RsS#VE4-$PIEEh$;f(y!6RK`;y zwnXR7&|7gqxe=8y)QGLE^3LPf_4Bx(+>FW~YQ&c4+%9@QE-1568AFZO5*<+KS9yho z8e&f<#Fpsf`ZZoT5cCq_8`B{Odd+VBcyr5kXwMs#PmhwR$UFn*NRcSgPV zRY(gVp2H%xB;J|VH|*BV`x=h8Ee~cS-^?h)mgqBpsdIMudzF~mg51O368uA0r{#74 zl-p4mLyg!H9Z>0`yeehyIWs2bZ5KPMSM6e_ouhWQPcG?q9{Dt^-?96Cx}@S=*VzUW z!aJ(~me>-#7+4>}1?4SN#!w@+j@hlBhI5VsqP&MnZ;4>*xPA81@btgYr_?8?^p*;? zL>~>V|Beev7b;_@5nH13B-F?3nzP|T8A&-6c8Jm!4*;{M5nJ!s>&~t(YDo) zEaUv9#84x)M0ff+_Q?702oap!CO6b5Nz{lf(b*A(Fzx(YZyJ6LC6wbnM#Nt8Ax0jt zThE7Yl|9FUM4!S1<}V&( z&gu$#-Y3O-239syWmmW%aYG6INFuqRh`oM$;pN8rngUzN_9ebZbZW$2{A9++oK#8- zHDYg022W#vZxVzn>)mqqqsoh#@CZ@L2;gx zk79YB579X?m#ZO%u5oRVN%NQ2o)SKB-j3jWFrFH*wDpN^%+LsjWG67uL{A=uig5 z`^4pI$Fwttvaz0#NNU7*A?04-FcyduN+-r*Zr2)o@`P zGKzCAvgw`q=g$EY8A(Ze#)wkjnOx!`ybNIP7d!^~rUcyTVf*R$eGNJV3y8`rb}~%x zXjoQHpC_0@`;p-Pgk|+&J`~KQ@S#^vj|zry7Lxk^03TH9SC8o#-kae9B)aloiM>5s z0PLOO&Xb53YVMN=fYMuT>H%0jrCxkgbZW%j8*E5Iyji664|0yM8T?QaM~PtTh&ics zG{*-WWv94H1zSFo=hNXF*=BEvdo8e6u2bEZ-%AWNVoUTFMepAYKU^3uJK><{)DH4XocAY!!wCueBFF8*u9*G@*Y*;x)9IL9%9Hbk0FgBlc!!9b@>mLg4@z zLyg#blNXE5lWPNf`frTJj|b7I5&NvanbB$byq;i+(sg4FAAFR%P(#J;^GO1*(fH=jjf?{zm0Sf4SwGVmzKo35PFX@3!e}_O;Oo%_6Q~heqC2l1 z==@uV@e)Jqyt|?EW@n4enV%<^GxJ@+jJY!bH*h`K*-v2qUGUG*F*$WkJ=d9-OXB=E z0A@^+=vN#_?Cy{ovrJ;B5nG}=yIX#BI^D?A;B+HhBHS5eDVlPAXAP&K zlu66d-^Q!3HtVZbA;+MDZl8AmhY(AR*b160Sy<;z)5?raNGQ3eT27C3z|5dVY@IQe zvvgUZoMzj^&Fx3*ea`^I0L_A4x~wAX_U(MLDRrmL`DP=!8_KIvJy1g<9q3%pL_7Y9 z6{cIzF{6WeZp8q%!6<{ry1~Sj=v2HTBpo<(0~NQRrM94R=$wXWkg0W|CU`N(E^vFu zgcK@sbz)0&Dtcf-49`;(Cq{H~U7Qe8K}BLjPotm*n+@4GSO@QI$<~+B0v1JlxyR1| zZJAxy>1cpk0;P?T-<+TnaHTFv0h85Fe=oq^QTV>cNwA_HqI$a021-56PD(stP+BQv znd6lB@fhVSrC!FL3yE7FB@dfU2Tggdo*T$^rAA8GW=pOf9^f`Y*-t5CI&$^OKyO#7 zPKDIlEbfn}KCZNyQXjLUzn&VvHzk(il)~m>fAq-50L70v(S1$v0JMdV3@lqHv!5$wwrdBoSddTjz;ntS z+Pkqp57B{QSKEc{ql?XJ)MHEOA!cKd zemzj)N;TM0y2LCk#!U`&rA?HEn%%`{Y?vz@q%_Q&WE9R5mMm;MJ=~NG(q$t`U1>fg z!3&8;xcagLyu!g|(;zf1XT?rRBh5jy6d2`ZbWs{*vIgT8N4rufcC{XDss|%#j4Rbs z8e=vNMq6@}v``vr+9=7%(Lw13)5W&NxrzMxtjC$sA&|zqQVpf?X6XYx%d$AY!`PB&#`~EVwgR9R`K4E z!*oXvy}?-H^&DT{WoE&6JzF=KXGt@DY%Y^7HZvz+-yAfXVSJP8Oy>kgEh}@>wPo0j z-!*&7bToCxefTYJ-UCFNDdoCIuP{SsTFhLUW^+GHo7wJ~*J&1;3p5?3UjlWu*#I&1iH`61x17RQ|*>*c0lzlU2P80+hi`#yV~@tf>~!K!T3rZGE1wRhHcX7 zHD*8QCi4M;J#SPCU;q#D-Lg`%)kLaTx}3W;1DlF>R#F%*UkDj0xS0{6?J5zc)AD zjQm<-7DB>vv-W00`86kRl^1t;}N83TBWX}LC zZ#LyKKs(Kyq_xdv9jMQrZ+270L_o$ZrObqBF+*so&0Ly8=6;%kW;=|pWScoO6B(1u z1*+>zziOB^GYQ7m?FqBA8qM~MnvG)j(`H4@NwNM}E*~v+f!HRoJH@t(y)3q1wwqTi zwodF8+F;bQiR}~{n&ax_w9%-2BGAVypQE#Uw@2-)Tl)0M4pf`FwopGCugR{46cMMR~ak)(=9DM!$1i#BKkf6)D&XYO2B_So~i=gghw zectz-nLG2&+`Bh<>3GW1ucvGrn08(H_19NiU;b41v@DpjTgd;vv=@0~A2+T&;w|=E zRvOaZE^`$-;tjSh7x?ddp7ti2NW4%XsvqshkuSZ^t9TXzm+9)p&$d7p)?v*{U zgYCOkt&;wfn=5)vOcj&%c_xj@8ty$kF4SJxe8?yN*Z$(?_sZYd(Fb$oF1zKyLiwxq zLl2IUX=xwUyq_wC{pE&hp9=QMxy&`i9l;n3gos z-xO{gC`aj=C>2g%*xw{akU^87aBCE$I-Ds>wbQViec{`R(*LymftSLvgjCf>h2>MS z?@0EBWg+#V^kds!t_dIidhgiC?Tw>Ho|r!@4ZeeE8{SujSPxE$d6O`f-1!&@hEXay z%A4f?nw;zS3ttx1XU`Hc7_-ZM@wR8}06Y7kC8^=z7-JuM-9s*NmU||S7O9`cL{ZLVH$=AqFw4b#{M;DGwmoHE)^40A89+c;)cs<2F@3nK6qz!&1=Djw2%oFz1 z?F%m&{QH>Bf{8&PUVSQ7Fs%JTRi9VeVheM}AAT}^kO9VT;N5xr1mqo79-M)?Lxpnb}=7t(Z^&@7UKC`UzeIWUDh@p#na zmjN@a$S(&zZusfR_MJ-y*h_!Y?E|CDl~M?Q`yIP)lTkNf9;m)1Vlgm>QO}%o7(A?7cB3ypspC{aa!HbXOQZGC?1EwH_6< zAb5)$tzR^VTcC45oL0Y>FYYjUmew1^I-~c|`a;nHo$<@HzDWE5x+@&O!36zl4^T33`*! z2ckv4_<>jtovlBw^`&Abbgt38TK}Q=Q$qYJ&=qvFEVg!m#sAD$va z1sZrm-{x{r3!N^`!Z(TU8-0`>z}=!5x+@&$`UL$E=+)ro>h_{5#eXL_JeQy!OVCdx z=16Y*{6%$!oKuMzi}01Oxl z|Ekyo-3wf-?Q6w8V~47jhKCu&>2RHR*Z6-8oL}58zKrvaa*Fz-(cMY)Oz~F{gw8cx zisBbP6BWizANt>vpifKCZ-%}Je$OC7{o?0hS%N)!MUUzRw_PE${>KFUSb}~kLBEio z_u}*!;eZE0=WG!B#V^EEqxTU}61G^85U>V%C7f63BzagooM8WTg1#R*JD99HP~wQu zuhsga;y83J@prYpMVy1K1^w$$#azPZ!QOcI0dGL@i^oI}bgua#t#1|Mp}WGnsy8}M zLBH50mO$r#xQu@BxM()|2(9lBj~YG7PW<8t@iYjIVT{&yi5HE-Sgr3CZ$Wp39bPnc z=Xh)r{c!HFL+6g46y-+G2Im)h#2lkLOYpS#k)ucTwD`qd@el}C=(NWKaN7LX8!si; z-@D5Gd(qo+qn#Noh0Xyv@z02v3HBA*UMobC?%;q}Zvq_skD?Vi_qDTT2gOs+IWT92 z{v@7aDnvgK9>M^Mp+ z3qWico+~b&#szX63Vp~CTZZS5e?NE0x|FEkg?1+QeWI(?z zIL%u}?0MZ=#=hiOr_-A5Scomd>yBS`d~P#7Bpw=yS0zkfnLLYL(mf-<~?BZ1j z`-dNn%6ZMfTm)I?VBJoaeelE2bB;UA6Q}}s_AoPut>bprM~mefc6CoM`iA3Egi4-p zFdL;mIbzH3Ck_8L>R~AIOVXHtLSsej(i-%b@Im>rkLrw6?_1%+?*m}cUtxI8K33G zha9o%!-SKacIZM7*UAfd(Jl}WjxWHOh3Kh&%fSVx$de4 zvrH5@V$1N%D0i`&j1M_t_g-{nnGvotKIDik!*4YFF4VVj#iTK`7y~(CH-J9?cpLAd zW_G!Qc*XGKh}}Wxj5}e6J`LuWsn5h?jVSn&e}UJ<+(c` zjmwX|ieMpz_4K9HIcK0kbe6%&3?;VC*eky%bFI&sSmq`%tcSi>ouY5jo;Pn$4v$Mn zFBJJt4c#5R=F2lV?>Wpvr~=nGVoO+`XljgKsAgGoY4aIdw!Olv*rZ0Iz?|sP8d&EcnfF z_@IkbFh#D2CMDswJqp7(Q4xc$L(SsyHyg~+-D&VD)GV$KzZDR3U3#NimoG6Gm0niz ze*iurgz}}zsqXXTBXG2ZP!qdZJp|a@?Rr1Mhn%yY0U-U%ZSl8M5p>r-&+z1k-P2@f zoWFW4RemSu7@NVXqcQMEAhwRF`ZSrB!w(>kHe-$$Y$d6UX-H3#bFUe51WKa-)mNnd4r$Pv2- zb{%~>)gCnG?vykp&R)a?@^{0NBeo3R3|(^5Kt4A<%?4YBUjyB3hu``* zyKB(D{_y8Ew2n?@&8{_0B z|G)+EPZYLFj@bH#nwKui@?Qt0pl_Nd7;G7SGEE+}2d$zyl8z&zw=>LfCW2d#*y^p4 z`{EJ8-#?J~#>|aGY#E+5JgZjr)sL*!zB1V8b0Yd{3+)&Ripe+UaoL58hntr?@KWGj z1}_7~Y-*lw1Qh!4-Fz`{U?{$$tAQDEjNGYib}BnV7Do9YpGG#MhYL($N96f|o*(sz z+3^a4*%_Zjv#R3_%P!E$p&1*6Gv)a*dVPau6YPB%%|hbhmH9->LQvmRE8gUk>NxSBh`ruqz8p9kt4P` zRh=JelcAO(B5EQkV37t7LL-bIM{F5hKYPIQC(HH5hq%^Y-tBaQIra4hb82okm_FZ$ z!_glYg^PTr!9PXE)Hw*w{oMw0O@3@JeeN@uYw|!GztLc>j~&M&L?;ewKT2SjP(RI* zzeKu*0!j67do`oEP%yRmi4@_Tj#8#H_W@Dk> zSCMQ)nA0Vf5g*_JS&za9a>UjLYDqTUCr<)HwxQ6>{3CWho&aKi>L^^t_ILXJ7N|hP zxhG=F@Qy35_-=v{7^$JYpos}VS%zwvQ|$=K*<+b-kUW&YbsB1H8J-L$hmwX8;CFi? zXsM#VK6P$E<$gBNUZY(fMCUs_q=O2Kad=|O@ML6RoDUCFi1sl&by*zeGnS0;F?=cs zIrNbn9IQk4_s@}^r~0`3kWF|kkX{uE$vmIWp$?JqshOnM6QqY!x@r!|+kJf%6?WM)Fnk;+v~`Es!jKQSqd*goy92N@-cRn<@|Pl*X7Ric`PqBR_;lw2ek z(sI{OIYat}Ib0L6Ob%1Y!{y7q;SMzuStf_8lf!Y7r4F^3RH+(LipFp_P>zr)Q}w0r zia1mTa#2Q93#bwNvkK%EQU*81;ibgpTv(~G>Q#ou%bl<`Qst_$42@SfR1c{N)m(;K z9OY0EB)S}>4$#XS8%?CHQ^^suWlo7*q`syqNL4z4$4OPH#t7QF-l6zCTwbqQNtuIV zCaKZtBm>Qv(M)QL@{Ryyj)*;^s#Fyzb0VB3HC8PlHO^^11G`O*Q!S)!aHwihH>jf{ zSd@nTs}foya@+^Ifis2Zevrh zU*g9yMBR8JqT1AAR+E*Ds`vncSLrb4;s!sM5L~a$Fse#f6EKjocdLpCvY@yTA{ffRbtg8o(rML;vt*RE4r)!m3b`vI{Qf(o- zQvDfKaUHg<&vT_Q_df1RXsb$PO+?f@HHKA#T7as!3ERn}{#CbeA|bd*wKHn3dJ~oB z;98YD3Aa&)4F9Sryas1e{QOs`*^>}`RNcd>Lv2S@(uLq-SB8B#6Mm8qeCdAGgU;kG zHE=SbbJdNkPOHVN8kLQzxIdEJy>B+@;!>V|(Defub*?%CcTdO9ly?f6Y*6J>(8y$U z8>*DEXk@y&Zwhky(t6cKhYHn6ha&Ykt2UK4712FP)lG%*pt=hxa&Zf)lny+?_Nf=9 z;w2=a{zbz&l~oJ(?k%dS7VceY0oBbdYCTlXC)cRGtdF#)lQgeXNp&#){xLPIPWL<; zDz@7_WOog+JClpZ@ZK|H?CUp-~Y`pELN&aY{zZ=>sR)q`ly?Rj=9j@Nr&#(~AJ zNm?9Q-8u`u+#1y4S?I4pd#c@_49@IGh-y%0;E4ch_LYFCvo8nu%kW5y@5Z$G%PTIK z-%NB-ooKA20r&M)lk^B5vT*}9Esn0oz~`&ldW>VfGw=sM8Jzi z?aTJ3f_ zZtTF+hwwPRF3av18}=Q+lQM)>Pr>+@9fR@RZ{v%ur6O}>{^ftV#eeVaziY01z2E-< DA@nE! delta 10977 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 aVtM(^+L^lW>;Ef?|8% Date: Tue, 14 Apr 2020 09:45:42 +0800 Subject: [PATCH 44/89] feat(wpa2_ent): add wifi_unregister_wpa2_cb --- components/esp8266/lib/VERSION | 2 +- components/esp8266/lib/libwpa2.a | Bin 25228 -> 25744 bytes components/esp8266/lib/libwpa2_dbg.a | Bin 29580 -> 30072 bytes 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index 088993b2f..3443bed2b 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -5,7 +5,7 @@ gwen: wpa: 7743eff5 espnow: 7743eff5 wps: 7743eff5 - wpa2: 9a2e4686 + wpa2: 705ad69a smartconfig: 2.8.2 phy: 1156.0 diff --git a/components/esp8266/lib/libwpa2.a b/components/esp8266/lib/libwpa2.a index e36eead2857bacd2b6078cc1f9f5460ee5ad1f4a..2b1784491739dd8253ea8665cf7bd3a18e8a29e9 100644 GIT binary patch delta 7240 zcmcgwYj9Q772f;agal8JJTBZ^L&)Qj+yo-Y4T%X}ZXOsQAcS`$yb?jh2O@*0eW;gO zK}s2gZmP6S87$OCtLPZ*SamQ`o#IT@GQ(KySbS9bgIZ*&b+ojk-*?X1$>oUs*){C5 zzx}Q6th4so`|Nwj&R6xW*YvJ&na%Z$Q{%hK3R9OflzP^8fl{hOsbJgxv*n~eZ1=#Q z3vSu4>FRaY-MsngO})2myt2M`?HXl@ODp>i>+fhUYm*E{g3XQfrY9IH*s}y#2bF3- zr&N_%pyu_PU~;rOj{j#c|K-!=(QU7ljf}q@-1+nPSA)|J?AKon4k(o!&k2;T-x@)r9|2~*=*`fnam+#NjpYi7M z8@JUzq{rTsY2pRN@li?*1k{Ux_(y~79}ec^>yN2P=8VWz`Y(iK?+sQ3#x7F&19$Xx zzbTjy&^i52jai#jh7u@Ur4;*Ov;bN)S}s~S+EkMpE;0qh6J`_&^ALJkHX3mVjdwkZ z=AiMe0W@;NN6?U?i{E6l{sYCSK>pWD-Ct0;?tHwtuKcHg=6aJEeasw==B6SDHf%vv zG&}$by3-h@g4|YV7F1od#+)uiD8P*7d$8`t{Aao>1~Z`|k` zH=Q$%2G!Jah@eXN#!2((gc38pqRt$utn2Tp=+ov z)#@^HQ>->Gs@{gC6zvAId{tqdjNPQ0Oi9&EdXl-Xs#nL&r&T3+Q`DVU{yJ#RXzChG zN%hhc_ZVxFj|u!6{$}6@+;Kvc<29-QzRw*eRV&8agRE`7YE`Q+&H!f1Q~wye**D(d z8~@BVek!O^=LC4kCphLCzvmnO(>KmSCg}+k`^L4t@$?Mr!}J>#`UD&Lzc=yA!2dXc zuF*fLt*(&G5JnwBs39W~JHi7hU1YjyqvKd!n5&fJT_t&w*IJ{en&)d5>r2grb>YaR zt`;X4!XoAd^o3|x+m^cUYzaP&jBK`RMM;j>N!x^)&w(*QDAR>*qB?2zAzIR7c!1~@ z50|5(k{q!kJiRvBWZ=*UGTyWi?QC5*l^(6lb*c&IsAM!^rwtdFd)T#mm=mUk9I+!j zH=WI@4VW5o#OKS(?1|?^B!}_TXL;EXJ4tgm9**!<7`HdQ%!=4)GpFL=q&#<;c$p9J z`SR%$4f7#(TFm6xVI4Nh>uW0{2Oc&dJc3Ulc7$hK-DVEe59Q-VgKRE5?yTF*iTdzt z$%n_fmUUkZ%$Vee?Pl|K2nZMt1Zv0;JJ>l>!jTq0*sW;va<>p8^9@tN6%@nVXUU#% zGr7p)-JBz)Womd-hsW@W?fu4-{^Sgg*?}%J(mRxh9pSm|dZwp&Ks4ltotfrvLpXAo z=Y2%HRp^PG%gm{UaB7z4{k3>&&=Wht*8$u592E^YVq2dEYBVk|S1Vy;TaH;NacR*49iN+GGFE?i|3FA7pDG}kS!rb)namD(% z>CZLSH$`>A+}jk!_2H&o`*PPJ(GZlpk=RaR0mhm;64opla>S1COEA{+OjmO_HIF)_ zmZ9k`7plc_7dc`__?6Vm_cZH7Lyp)HzKdsN&h zJUL=}RJhA4F9Gl2z2u0k#@!B!K)|~8;zAKgVn-bNh5rruIy5`SUkXo-*q+1g-b(rE)@b5qVJ@BDK4Q1{40S6mu>EM%kRx`4F9o)!_FwTSI=-T5v90ZXAV0y$!5ndxc?N2JbN#n5P6U~ZkSFn7Xx zg~zm`qjx)cK0|k#LoMM7dAj=)!Rtgxj@aooCtG@TNB^AG2XsUhcnP-xs?Aao<8A&| zTOuMw=gUv8TSR)BOjmm}(gQKBvftdJSO@wUNBY&Qy*-)`a?L_>}kOL%0)gL;)&Ju{qI1roLZP4mry zeJFZz#E$T%g)c-!m%yi2Q?1lz!jmI*gkOfS{T&W)MKB9;#P%o5d_J=WuV~k-p;z=; z-X*KtCU=n|wyVEBE%JQPkR!H{H>PP;i-sJr)oi9_IxaBt(X70P;Ps;4joEw)K4f@d zXV~uNJH-1OJh#)^Yg#(Psa`(`5!)}O?bOH@ z(+i>@N9+i18fND$m6x9{YbYNVSTP!L2Kpkw)#$U)?CL~?Cr51SGl7~S^QX=zzGlvL z&PqxA4(bbVfz3xFX8h{}GtLIV%;jdmx#(F>>O<)75L}3UtKb3j_X;jWzgsZRhtxh9 z96|qxU?$1Ga4;wXwF`a-{anG+SE1?j-w^1@ad$hyUjxiI)PG;_576)Qa7qmT)SwNm zu;*~O`+@BW*HP1l3yg^{C^=%M4;R?uXyloE1DYO*3(P%lz>{;&8}P(0s4VY>0em8r z>aqCxj;6R2usB+XC52s&M$8qtQ7~7;tu}Z*cZ={j=-r8e=jv<|p86jOei*%5cxdp? zn-2grDOOxB!v!`IjSnVA>sNPWAT!{0le}&byYc3eo@~9$yxtSbfia)Ig^#@6Lm?N`eUe$3DeCqv3dKx(9-I%5>&M;rBu1prWi>B7e7I6 zge|@Z&*8m0C=rrr5uWfxsLR7AtQ+A`Uxbx&ybmFk4J8@M;h03gzH#jaL?|{N^c0Nw z8$38o6l(3-c6hQGd(4^hcrskin9Q%=<9RB+(bN1*o@56+T%)?Q3|K#F^s&u@4(ITY z{T7)vyL0H32-bB5p8fQsmcxT-488U5qdxWknhl;l9&YP>5gx>c-YYDN7@tpD=Zp6T zeD6@ldh^rA#zO+Es3}@AGPAcxsas6-n&_zGrI;nAFdyC~)3c_iFr!MTdw7$Wea?RY D7W?-` delta 6902 zcmcgwYj9Q78QnWKK*9--klUPG9?1TAu9L$U0l73gtDsaiOtO4Rvk(ePuT)+weW zyQbnqL3-8Sv!4ERB{{6=j@uiMRI#dC-AW)EufNpW0vn`5y7ooDh(Ds|K>DXGkw zrQXDgQIyRnQ&o|;I_K*YobV&MxDKO)xhP>w9P<)8!UHNj&Gf|! zBeK$-QhMYm>&>ptLetouq34)q;wvJu0~X=UFw%wLiJb;hQRVhX-U}s~3r}p@A7Zcwc9fn5XP-#`_K-|x5yEX?E?symwAGZF?gk$&EaY{ zA|omV6GpTf-Wy$;c?VHxom0;!hbBFlT;mp>r6+u!O7?`asrlQu3i1J6G zWIHn$Z87U>T|5^rawl;s!o18mrlQH!xu&Asoz&s;d}1G;tQ{`y^qJe?!s-5%LhK07 z`PcK!;W{@m-&YS7swe>2T|9H z$trcNygMk^5&mZ3_rMP!X78Te!jmJ$7_rMzxiY4zH;m1-FJ5TYHDzE^UD|YPl^mJP zh=-jszf<;;l1T+0f22qp`IMEy%4q9N=3(K<5!;K@+j!D*zQdg4h;7fy8c?zK*9#&dM{K*xKI&zrt;J0&1BA7s=;cI8 zeT>4??SdWQPYa)l`JE4JyZf#1;Kq6=sEI2BGW@$n2e^5lq}CH{#r%Uf6214U^VABJi0#5hn-wYoOCQKC#v zjOZt=qd$f}m1rhBvAr0=z?vrlb~_65lOuM7&jr>i&Eht=(tW0Ft{dqCgx!Kd7!$VtU%} zi=7D_xzMja1{cPkG;D_0xzJp^pfVxn{3VI9A!2*ZKMm>RUM2Q`ITJ^Yzb$nB)?Gn8~up|67)a_3AjcCXb+nsPg z_@nUKsh1C_gTj*|wjWrxQp2T$ndf@4Qi;u~&T@RHY*@4~F~^Ijd2r#WKIVl=oC?25 za2os;!5Q%0*C8~Sz#Js?VfY&b=fdAC_;vU@1V`cT5R*ajXem@JxI)VOHj0YZt-Z6Cr9iEzd?BFf8pbVx(#5b1lZGZ6uSs_3r~*NF2W(< zABT^l*iCvwcyh#c;~W>B1F1#P>3G1NRr!8TNj{6>AVB;w3PIbz2=9nUr!7r!~&yX5)_Jy>Mgwh4Gc@XjQ>CkY=&!bg(ulO8scS2q`9 zM6^_NP7BUV!ZSQ zj{j|W9_nnEG0xK#)3Y{Kx+$RkFiAZvNxjqD1NAKdbsUp@8Y<@IwzIh(F&{zwP(U3$ zSE)f!=OwA1GmYzFWyb>QZBQQ)bu>x+Zi=~m-R!b|1mqi`*<=XFgQIgy>rR!s*Q$u6tFdWAN;~h)bW7&LtG!n!EshflGMx038;Gm z>O=VZ@(c8i>aryD1``>Gm0lE3|F*&Z3zur{bUWieH=CfoF`#}E>T9Im81SfipLqi6 zdjjg-CZ&!-#oQS1sQS+)eK1z~$ADTjpHWvQsoyde493d-7Em9Bx&<6_^Yq$&e-|6*Uoaih(i{Ndc2;25EWm{Pqp*5CxS zpiszT`YTC@&U@C0gfj)xaW-fNq4O>Tzp4h!RTsNifA}BvX|S)HmHpRQ*)Ptb%}x=%Nb3$dyy|>!frEZX!^JjTzXaJ+@Zor@hC|2y%(;|tQ(r1 O8;>b<1=|#}Y5xnPd8`2d diff --git a/components/esp8266/lib/libwpa2_dbg.a b/components/esp8266/lib/libwpa2_dbg.a index 9b7d7ed2b77d344c1305a03865eae25e05e7f17d..caabfed9ee2226de68c4aa57b0c6699ecc35b496 100644 GIT binary patch delta 8297 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 IG1Jfg0Do+n^8f$< delta 8005 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 JIx*9O{{TyCG_(K! From 86917bc8967a089e59e01d8736bbbd8306ccd84c Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 20 Apr 2020 17:42:00 +0800 Subject: [PATCH 45/89] feat(lwip): add shutdown to socket_mt --- components/lwip/apps/multi-threads/sockets_mt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/lwip/apps/multi-threads/sockets_mt.c b/components/lwip/apps/multi-threads/sockets_mt.c index e339251aa..e5e26ea92 100644 --- a/components/lwip/apps/multi-threads/sockets_mt.c +++ b/components/lwip/apps/multi-threads/sockets_mt.c @@ -769,7 +769,7 @@ int lwip_fcntl(int s, int cmd, int val) int lwip_shutdown(int s, int how) { - return 0; + return lwip_shutdown_esp(s, how); } int lwip_close(int s) From cb21ade204c77e2b8c0e441acd372ee1270a9229 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 20 Apr 2020 18:51:47 +0800 Subject: [PATCH 46/89] fix(lwip): fix IGMP join wrong address --- components/lwip/lwip/src/core/ipv6/mld6.c | 4 ++++ 1 file changed, 4 insertions(+) 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) { From 34c2d463b222258d064609047a17f1b96b77f7f5 Mon Sep 17 00:00:00 2001 From: Zhang Jun Hao Date: Mon, 20 Apr 2020 20:21:06 +0800 Subject: [PATCH 47/89] fix(lib): fix return code error when set wrong authmode in softap config --- components/esp8266/lib/VERSION | 4 ++-- components/esp8266/lib/libcore.a | Bin 91842 -> 91950 bytes components/esp8266/lib/libcore_dbg.a | Bin 93106 -> 93214 bytes components/esp8266/lib/libnet80211.a | Bin 394340 -> 394276 bytes components/esp8266/lib/libnet80211_dbg.a | Bin 433720 -> 433656 bytes 5 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index 3443bed2b..6bb1e3de5 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -1,6 +1,6 @@ gwen: - core: c15eecf2 - net80211: 7743eff5 + core: f4de8f12 + net80211: f4de8f12 pp: 7743eff5 wpa: 7743eff5 espnow: 7743eff5 diff --git a/components/esp8266/lib/libcore.a b/components/esp8266/lib/libcore.a index df3fff748790cd7755b825dc31b05afbb274b266..309353ff709a6bddb71e635ec20596d847fd9bac 100755 GIT binary patch delta 5515 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