Files
esphome/esphome/core/hash_base.h
J. Nick Koston 9003844eda [core] Fix ESP32-S2/S3 hardware SHA crash by aligning HashBase digest buffer (#13234)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2026-01-15 18:29:11 +00:00

59 lines
1.9 KiB
C++

#pragma once
#include <cstdint>
#include <cstddef>
#include <cstring>
#include "esphome/core/helpers.h"
namespace esphome {
/// Base class for hash algorithms
class HashBase {
public:
virtual ~HashBase() = default;
/// Initialize a new hash computation
virtual void init() = 0;
/// Add bytes of data for the hash
virtual void add(const uint8_t *data, size_t len) = 0;
void add(const char *data, size_t len) { this->add((const uint8_t *) data, len); }
/// Compute the hash based on provided data
virtual void calculate() = 0;
/// Retrieve the hash as bytes
void get_bytes(uint8_t *output) { memcpy(output, this->digest_, this->get_size()); }
/// Retrieve the hash as hex characters. Output buffer must hold get_size() * 2 + 1 bytes.
void get_hex(char *output) { format_hex_to(output, this->get_size() * 2 + 1, this->digest_, this->get_size()); }
/// Compare the hash against a provided byte-encoded hash
bool equals_bytes(const uint8_t *expected) { return memcmp(this->digest_, expected, this->get_size()) == 0; }
/// Compare the hash against a provided hex-encoded hash
bool equals_hex(const char *expected) {
uint8_t parsed[32]; // Fixed size for max hash (SHA256 = 32 bytes)
if (!parse_hex(expected, parsed, this->get_size())) {
return false;
}
return this->equals_bytes(parsed);
}
/// Get the size of the hash in bytes (16 for MD5, 32 for SHA256)
virtual size_t get_size() const = 0;
protected:
// ESP32 variants with DMA-based hardware SHA (all except original ESP32) require 32-byte aligned buffers.
// Original ESP32 uses a different hardware SHA implementation without DMA alignment requirements.
// Other platforms (ESP8266, RP2040, LibreTiny) use software SHA and don't need alignment.
// Storage sized for max(MD5=16, SHA256=32) bytes
#if defined(USE_ESP32) && !defined(USE_ESP32_VARIANT_ESP32)
alignas(32) uint8_t digest_[32];
#else
uint8_t digest_[32];
#endif
};
} // namespace esphome