[xxtea] Extract encryption functions to separate component (#8183)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
Clyde Stubbs 2025-02-05 10:22:40 +11:00 committed by GitHub
parent 9b56f9cc6d
commit 1215d2ffeb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 82 additions and 51 deletions

View File

@ -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

View File

@ -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")

View File

@ -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) {

View File

@ -0,0 +1,3 @@
"""ESPHome XXTEA encryption component."""
CODEOWNERS = ["@clydebarrow"]

View File

@ -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

View File

@ -0,0 +1,26 @@
#pragma once
#include <cstdint>
#include <cstddef>
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