From 9713458368dfb9fd9aab8016cfe8c85d77b04887 Mon Sep 17 00:00:00 2001 From: tomaszduda23 Date: Thu, 15 Aug 2024 07:17:38 +0200 Subject: [PATCH 1/6] [code-quality] fix clang-tidy improv_serial (#7283) --- esphome/components/improv_serial/improv_serial_component.cpp | 3 ++- esphome/components/improv_serial/improv_serial_component.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/improv_serial/improv_serial_component.cpp b/esphome/components/improv_serial/improv_serial_component.cpp index 425a5c8576..c3a0f2eacc 100644 --- a/esphome/components/improv_serial/improv_serial_component.cpp +++ b/esphome/components/improv_serial/improv_serial_component.cpp @@ -1,5 +1,5 @@ #include "improv_serial_component.h" - +#ifdef USE_WIFI #include "esphome/core/application.h" #include "esphome/core/defines.h" #include "esphome/core/hal.h" @@ -313,3 +313,4 @@ ImprovSerialComponent *global_improv_serial_component = // NOLINT(cppcoreguidel } // namespace improv_serial } // namespace esphome +#endif diff --git a/esphome/components/improv_serial/improv_serial_component.h b/esphome/components/improv_serial/improv_serial_component.h index f737f93d86..5d2534c2fc 100644 --- a/esphome/components/improv_serial/improv_serial_component.h +++ b/esphome/components/improv_serial/improv_serial_component.h @@ -5,7 +5,7 @@ #include "esphome/core/component.h" #include "esphome/core/defines.h" #include "esphome/core/helpers.h" - +#ifdef USE_WIFI #include #include @@ -78,3 +78,4 @@ extern ImprovSerialComponent } // namespace improv_serial } // namespace esphome +#endif From abb2669f0fb94c72deb55781bb087c86fe2e382c Mon Sep 17 00:00:00 2001 From: tomaszduda23 Date: Thu, 15 Aug 2024 23:16:06 +0200 Subject: [PATCH 2/6] [code-quality] fix clang-tidy captive_portal (#7280) --- esphome/components/captive_portal/captive_portal.cpp | 2 ++ esphome/components/captive_portal/captive_portal.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/esphome/components/captive_portal/captive_portal.cpp b/esphome/components/captive_portal/captive_portal.cpp index 630e00f0b7..d1960e9a93 100644 --- a/esphome/components/captive_portal/captive_portal.cpp +++ b/esphome/components/captive_portal/captive_portal.cpp @@ -1,4 +1,5 @@ #include "captive_portal.h" +#ifdef USE_CAPTIVE_PORTAL #include "esphome/core/log.h" #include "esphome/core/application.h" #include "esphome/components/wifi/wifi_component.h" @@ -91,3 +92,4 @@ CaptivePortal *global_captive_portal = nullptr; // NOLINT(cppcoreguidelines-avo } // namespace captive_portal } // namespace esphome +#endif diff --git a/esphome/components/captive_portal/captive_portal.h b/esphome/components/captive_portal/captive_portal.h index df45d40d12..24d1295e6a 100644 --- a/esphome/components/captive_portal/captive_portal.h +++ b/esphome/components/captive_portal/captive_portal.h @@ -1,5 +1,6 @@ #pragma once - +#include "esphome/core/defines.h" +#ifdef USE_CAPTIVE_PORTAL #include #ifdef USE_ARDUINO #include @@ -71,3 +72,4 @@ extern CaptivePortal *global_captive_portal; // NOLINT(cppcoreguidelines-avoid- } // namespace captive_portal } // namespace esphome +#endif From 9001d1c0d46cf214f989baac9c1f05f4ed321804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Kiss?= <70820303+g-kiss@users.noreply.github.com> Date: Fri, 16 Aug 2024 00:35:00 +0200 Subject: [PATCH 3/6] Fix overflow in ESPColorCorrection object (#7268) --- esphome/components/light/esp_color_correction.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/esphome/components/light/esp_color_correction.h b/esphome/components/light/esp_color_correction.h index eedd71ab27..979a1acb07 100644 --- a/esphome/components/light/esp_color_correction.h +++ b/esphome/components/light/esp_color_correction.h @@ -41,29 +41,29 @@ class ESPColorCorrection { if (this->max_brightness_.red == 0 || this->local_brightness_ == 0) return 0; uint16_t uncorrected = this->gamma_reverse_table_[red] * 255UL; - uint8_t res = ((uncorrected / this->max_brightness_.red) * 255UL) / this->local_brightness_; - return res; + uint16_t res = ((uncorrected / this->max_brightness_.red) * 255UL) / this->local_brightness_; + return (uint8_t) std::min(res, uint16_t(255)); } inline uint8_t color_uncorrect_green(uint8_t green) const ESPHOME_ALWAYS_INLINE { if (this->max_brightness_.green == 0 || this->local_brightness_ == 0) return 0; uint16_t uncorrected = this->gamma_reverse_table_[green] * 255UL; - uint8_t res = ((uncorrected / this->max_brightness_.green) * 255UL) / this->local_brightness_; - return res; + uint16_t res = ((uncorrected / this->max_brightness_.green) * 255UL) / this->local_brightness_; + return (uint8_t) std::min(res, uint16_t(255)); } inline uint8_t color_uncorrect_blue(uint8_t blue) const ESPHOME_ALWAYS_INLINE { if (this->max_brightness_.blue == 0 || this->local_brightness_ == 0) return 0; uint16_t uncorrected = this->gamma_reverse_table_[blue] * 255UL; - uint8_t res = ((uncorrected / this->max_brightness_.blue) * 255UL) / this->local_brightness_; - return res; + uint16_t res = ((uncorrected / this->max_brightness_.blue) * 255UL) / this->local_brightness_; + return (uint8_t) std::min(res, uint16_t(255)); } inline uint8_t color_uncorrect_white(uint8_t white) const ESPHOME_ALWAYS_INLINE { if (this->max_brightness_.white == 0 || this->local_brightness_ == 0) return 0; uint16_t uncorrected = this->gamma_reverse_table_[white] * 255UL; - uint8_t res = ((uncorrected / this->max_brightness_.white) * 255UL) / this->local_brightness_; - return res; + uint16_t res = ((uncorrected / this->max_brightness_.white) * 255UL) / this->local_brightness_; + return (uint8_t) std::min(res, uint16_t(255)); } protected: From c3668b9a4de8408c28089c8c0652e0c36119cdcd Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Fri, 16 Aug 2024 11:05:26 +1200 Subject: [PATCH 4/6] [validation] Allow ``maybe_simple_value`` to not have default key in complex value (#7294) --- esphome/config_validation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/config_validation.py b/esphome/config_validation.py index ef60d6e0d6..1c00e0699b 100644 --- a/esphome/config_validation.py +++ b/esphome/config_validation.py @@ -1850,7 +1850,7 @@ def maybe_simple_value(*validators, **kwargs): if value == SCHEMA_EXTRACT: return (validator, key) - if isinstance(value, dict) and key in value: + if isinstance(value, dict): return validator(value) return validator({key: value}) From a0c54504cdc54521309364609883c002f88ae137 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 16 Aug 2024 00:27:23 +0100 Subject: [PATCH 5/6] Add HMAC-MD5 support for authenticating OTA updates (#7200) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- CODEOWNERS | 1 + esphome/components/hmac_md5/__init__.py | 2 + esphome/components/hmac_md5/hmac_md5.cpp | 56 ++++++++++++++++++++++++ esphome/components/hmac_md5/hmac_md5.h | 48 ++++++++++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 esphome/components/hmac_md5/__init__.py create mode 100644 esphome/components/hmac_md5/hmac_md5.cpp create mode 100644 esphome/components/hmac_md5/hmac_md5.h diff --git a/CODEOWNERS b/CODEOWNERS index 1236c8d842..9159f5f843 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -169,6 +169,7 @@ esphome/components/he60r/* @clydebarrow esphome/components/heatpumpir/* @rob-deutsch esphome/components/hitachi_ac424/* @sourabhjaiswal esphome/components/hm3301/* @freekode +esphome/components/hmac_md5/* @dwmw2 esphome/components/homeassistant/* @OttoWinter @esphome/core esphome/components/homeassistant/number/* @landonr esphome/components/homeassistant/switch/* @Links2004 diff --git a/esphome/components/hmac_md5/__init__.py b/esphome/components/hmac_md5/__init__.py new file mode 100644 index 0000000000..fe245c0cfd --- /dev/null +++ b/esphome/components/hmac_md5/__init__.py @@ -0,0 +1,2 @@ +AUTO_LOAD = ["md5"] +CODEOWNERS = ["@dwmw2"] diff --git a/esphome/components/hmac_md5/hmac_md5.cpp b/esphome/components/hmac_md5/hmac_md5.cpp new file mode 100644 index 0000000000..90bf91882f --- /dev/null +++ b/esphome/components/hmac_md5/hmac_md5.cpp @@ -0,0 +1,56 @@ +#include +#include +#include "hmac_md5.h" +#include "esphome/core/helpers.h" + +namespace esphome { +namespace hmac_md5 { +void HmacMD5::init(const uint8_t *key, size_t len) { + uint8_t ipad[64], opad[64]; + + memset(ipad, 0, sizeof(ipad)); + if (len > 64) { + md5::MD5Digest keymd5; + keymd5.init(); + keymd5.add(key, len); + keymd5.calculate(); + keymd5.get_bytes(ipad); + } else { + memcpy(ipad, key, len); + } + memcpy(opad, ipad, sizeof(opad)); + + for (int i = 0; i < 64; i++) { + ipad[i] ^= 0x36; + opad[i] ^= 0x5c; + } + + this->ihash_.init(); + this->ihash_.add(ipad, sizeof(ipad)); + + this->ohash_.init(); + this->ohash_.add(opad, sizeof(opad)); +} + +void HmacMD5::add(const uint8_t *data, size_t len) { this->ihash_.add(data, len); } + +void HmacMD5::calculate() { + uint8_t ibytes[16]; + + this->ihash_.calculate(); + this->ihash_.get_bytes(ibytes); + + this->ohash_.add(ibytes, sizeof(ibytes)); + this->ohash_.calculate(); +} + +void HmacMD5::get_bytes(uint8_t *output) { this->ohash_.get_bytes(output); } + +void HmacMD5::get_hex(char *output) { this->ohash_.get_hex(output); } + +bool HmacMD5::equals_bytes(const uint8_t *expected) { return this->ohash_.equals_bytes(expected); } + +bool HmacMD5::equals_hex(const char *expected) { return this->ohash_.equals_hex(expected); } + +} // namespace hmac_md5 +} // namespace esphome diff --git a/esphome/components/hmac_md5/hmac_md5.h b/esphome/components/hmac_md5/hmac_md5.h new file mode 100644 index 0000000000..e6a97ad2e3 --- /dev/null +++ b/esphome/components/hmac_md5/hmac_md5.h @@ -0,0 +1,48 @@ +#pragma once + +#include "esphome/core/defines.h" +#include "esphome/components/md5/md5.h" + +#include + +namespace esphome { +namespace hmac_md5 { + +class HmacMD5 { + public: + HmacMD5() = default; + ~HmacMD5() = default; + + /// Initialize a new MD5 digest computation. + void init(const uint8_t *key, size_t len); + void init(const char *key, size_t len) { this->init((const uint8_t *) key, len); } + void init(const std::string &key) { this->init(key.c_str(), key.length()); } + + /// Add bytes of data for the digest. + void add(const uint8_t *data, size_t len); + void add(const char *data, size_t len) { this->add((const uint8_t *) data, len); } + + /// Compute the digest, based on the provided data. + void calculate(); + + /// Retrieve the HMAC-MD5 digest as bytes. + /// The output must be able to hold 16 bytes or more. + void get_bytes(uint8_t *output); + + /// Retrieve the HMAC-MD5 digest as hex characters. + /// The output must be able to hold 32 bytes or more. + void get_hex(char *output); + + /// Compare the digest against a provided byte-encoded digest (16 bytes). + bool equals_bytes(const uint8_t *expected); + + /// Compare the digest against a provided hex-encoded digest (32 bytes). + bool equals_hex(const char *expected); + + protected: + md5::MD5Digest ihash_; + md5::MD5Digest ohash_; +}; + +} // namespace hmac_md5 +} // namespace esphome From a7167ec3bf1adaec467944586c71d442a93a68d2 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 16 Aug 2024 02:32:00 +0100 Subject: [PATCH 6/6] [network] Always allow ``enable_ipv6: false`` (#7291) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- esphome/components/network/__init__.py | 6 +++++- esphome/config_validation.py | 14 ++++++++++++++ tests/components/network/test-ipv6.bk72xx-ard.yaml | 4 ++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/components/network/test-ipv6.bk72xx-ard.yaml diff --git a/esphome/components/network/__init__.py b/esphome/components/network/__init__.py index 96db322bde..caa873a746 100644 --- a/esphome/components/network/__init__.py +++ b/esphome/components/network/__init__.py @@ -24,7 +24,11 @@ CONFIG_SCHEMA = cv.Schema( esp32=False, rp2040=False, ): cv.All( - cv.boolean, cv.only_on([PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_RP2040]) + cv.boolean, + cv.Any( + cv.only_on([PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_RP2040]), + cv.boolean_false, + ), ), cv.Optional(CONF_MIN_IPV6_ADDR_COUNT, default=0): cv.positive_int, } diff --git a/esphome/config_validation.py b/esphome/config_validation.py index 1c00e0699b..6d6cb451d6 100644 --- a/esphome/config_validation.py +++ b/esphome/config_validation.py @@ -370,6 +370,20 @@ def boolean(value): ) +def boolean_false(value): + """Validate the given config option to be a boolean, set to False. + + This option allows a bunch of different ways of expressing boolean values: + - instance of boolean + - 'true'/'false' + - 'yes'/'no' + - 'enable'/disable + """ + if boolean(value): + raise Invalid("Expected boolean value to be false") + return False + + @schema_extractor_list def ensure_list(*validators): """Validate this configuration option to be a list. diff --git a/tests/components/network/test-ipv6.bk72xx-ard.yaml b/tests/components/network/test-ipv6.bk72xx-ard.yaml new file mode 100644 index 0000000000..361ca09977 --- /dev/null +++ b/tests/components/network/test-ipv6.bk72xx-ard.yaml @@ -0,0 +1,4 @@ +substitutions: + network_enable_ipv6: "false" + +<<: !include common.yaml