diff --git a/CODEOWNERS b/CODEOWNERS index d26e153c1a..03e26bcb84 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -499,5 +499,6 @@ esphome/components/xiaomi_mhoc401/* @vevsvevs esphome/components/xiaomi_rtcgq02lm/* @jesserockz esphome/components/xl9535/* @mreditor97 esphome/components/xpt2046/touchscreen/* @nielsnl68 @numo68 +esphome/components/xxtea/* @clydebarrow esphome/components/zhlt01/* @cfeenstra1024 esphome/components/zio_ultrasonic/* @kahrendt diff --git a/esphome/components/udp/__init__.py b/esphome/components/udp/__init__.py index 5485663f1c..140d1e4236 100644 --- a/esphome/components/udp/__init__.py +++ b/esphome/components/udp/__init__.py @@ -18,7 +18,7 @@ from esphome.cpp_generator import MockObjClass CODEOWNERS = ["@clydebarrow"] DEPENDENCIES = ["network"] -AUTO_LOAD = ["socket"] +AUTO_LOAD = ["socket", "xxtea"] MULTI_CONF = True udp_ns = cg.esphome_ns.namespace("udp") diff --git a/esphome/components/udp/udp_component.cpp b/esphome/components/udp/udp_component.cpp index 30f7356879..59cba8c7fe 100644 --- a/esphome/components/udp/udp_component.cpp +++ b/esphome/components/udp/udp_component.cpp @@ -3,6 +3,8 @@ #include "esphome/components/network/util.h" #include "udp_component.h" +#include "esphome/components/xxtea/xxtea.h" + namespace esphome { namespace udp { @@ -47,54 +49,7 @@ namespace udp { */ static const char *const TAG = "udp"; -/** - * XXTEA implementation, using 256 bit key. - */ - -static const uint32_t DELTA = 0x9e3779b9; -#define MX ((((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((sum ^ y) + (k[(p ^ e) & 7] ^ z))) - -/** - * Encrypt a block of data in-place - */ - -static void xxtea_encrypt(uint32_t *v, size_t n, const uint32_t *k) { - uint32_t z, y, sum, e; - size_t p; - size_t q = 6 + 52 / n; - sum = 0; - z = v[n - 1]; - while (q-- != 0) { - sum += DELTA; - e = (sum >> 2); - for (p = 0; p != n - 1; p++) { - y = v[p + 1]; - z = v[p] += MX; - } - y = v[0]; - z = v[n - 1] += MX; - } -} - -static void xxtea_decrypt(uint32_t *v, size_t n, const uint32_t *k) { - uint32_t z, y, sum, e; - size_t p; - size_t q = 6 + 52 / n; - sum = q * DELTA; - y = v[0]; - while (q-- != 0) { - e = (sum >> 2); - for (p = n - 1; p != 0; p--) { - z = v[p - 1]; - y = v[p] -= MX; - } - z = v[n - 1]; - y = v[0] -= MX; - sum -= DELTA; - } -} - -inline static size_t round4(size_t value) { return (value + 3) & ~3; } +static size_t round4(size_t value) { return (value + 3) & ~3; } union FuData { uint32_t u32; @@ -312,7 +267,7 @@ void UDPComponent::flush_() { memcpy(buffer, this->header_.data(), this->header_.size()); memcpy(buffer + header_len, this->data_.data(), this->data_.size()); if (this->is_encrypted_()) { - xxtea_encrypt(buffer + header_len, len, (uint32_t *) this->encryption_key_.data()); + xxtea::encrypt(buffer + header_len, len, (uint32_t *) this->encryption_key_.data()); } auto total_len = (header_len + len) * 4; this->send_packet_(buffer, total_len); @@ -503,7 +458,7 @@ void UDPComponent::process_(uint8_t *buf, const size_t len) { #endif if (!provider.encryption_key.empty()) { - xxtea_decrypt((uint32_t *) buf, (end - buf) / 4, (uint32_t *) provider.encryption_key.data()); + xxtea::decrypt((uint32_t *) buf, (end - buf) / 4, (uint32_t *) provider.encryption_key.data()); } byte = *buf++; if (byte == ROLLING_CODE_KEY) { diff --git a/esphome/components/xxtea/__init__.py b/esphome/components/xxtea/__init__.py new file mode 100644 index 0000000000..7a7bce1781 --- /dev/null +++ b/esphome/components/xxtea/__init__.py @@ -0,0 +1,3 @@ +"""ESPHome XXTEA encryption component.""" + +CODEOWNERS = ["@clydebarrow"] diff --git a/esphome/components/xxtea/xxtea.cpp b/esphome/components/xxtea/xxtea.cpp new file mode 100644 index 0000000000..aae663ee01 --- /dev/null +++ b/esphome/components/xxtea/xxtea.cpp @@ -0,0 +1,46 @@ +#include "xxtea.h" + +namespace esphome { +namespace xxtea { + +static const uint32_t DELTA = 0x9e3779b9; +#define MX ((((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((sum ^ y) + (k[(p ^ e) & 7] ^ z))) + +void encrypt(uint32_t *v, size_t n, const uint32_t *k) { + uint32_t z, y, sum, e; + size_t p; + size_t q = 6 + 52 / n; + sum = 0; + z = v[n - 1]; + while (q-- != 0) { + sum += DELTA; + e = (sum >> 2); + for (p = 0; p != n - 1; p++) { + y = v[p + 1]; + z = v[p] += MX; + } + y = v[0]; + z = v[n - 1] += MX; + } +} + +void decrypt(uint32_t *v, size_t n, const uint32_t *k) { + uint32_t z, y, sum, e; + size_t p; + size_t q = 6 + 52 / n; + sum = q * DELTA; + y = v[0]; + while (q-- != 0) { + e = (sum >> 2); + for (p = n - 1; p != 0; p--) { + z = v[p - 1]; + y = v[p] -= MX; + } + z = v[n - 1]; + y = v[0] -= MX; + sum -= DELTA; + } +} + +} // namespace xxtea +} // namespace esphome diff --git a/esphome/components/xxtea/xxtea.h b/esphome/components/xxtea/xxtea.h new file mode 100644 index 0000000000..86afbd1d46 --- /dev/null +++ b/esphome/components/xxtea/xxtea.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +namespace esphome { +namespace xxtea { + +/** + * Encrypt a block of data in-place using XXTEA algorithm with 256-bit key + * @param v Data to encrypt (as array of 32-bit words) + * @param n Number of 32-bit words in data + * @param k Key (array of 8 32-bit words) + */ +void encrypt(uint32_t *v, size_t n, const uint32_t *k); + +/** + * Decrypt a block of data in-place using XXTEA algorithm with 256-bit key + * @param v Data to decrypt (as array of 32-bit words) + * @param n Number of 32-bit words in data + * @param k Key (array of 8 32-bit words) + */ +void decrypt(uint32_t *v, size_t n, const uint32_t *k); + +} // namespace xxtea +} // namespace esphome