ESPHome 2026.9.0
Loading...
Searching...
No Matches
noise.h
Go to the documentation of this file.
1#pragma once
3#ifdef USE_NOISE
4#include <array>
5#include <cstddef>
6#include <cstdint>
7#include "esphome/core/log.h"
8
9namespace esphome::noise {
10
11using psk_t = std::array<uint8_t, 32>;
12
14 public:
15 // The all-zeros PSK is reserved: it marks the device as unprovisioned and
16 // doubles as the well-known provisioning PSK that unprovisioned devices
17 // accept for Noise handshakes (passive-sniffing protection only, no
18 // authentication). It is never a valid real key.
19 static bool is_all_zeros(const psk_t &psk) {
20 uint8_t acc = 0;
21 for (uint8_t b : psk) {
22 acc |= b;
23 }
24 return acc == 0;
25 }
29 void set_psk(const uint8_t *psk) { this->psk_ = psk; }
31 void load_psk(psk_t &out) const;
32 bool has_psk() const { return this->psk_ != nullptr; }
33
34 protected:
35 const uint8_t *psk_{nullptr};
36};
37
39const LogString *noise_err_to_logstr(int err);
40
41// Shared wire format for the noise transports (api and ota): every frame is
42// FRAME_INDICATOR, a 16-bit big-endian payload length, then the payload.
43// Handshake payloads start with a status byte; transport payloads end with
44// the ChaCha20-Poly1305 MAC.
45static constexpr uint8_t FRAME_INDICATOR = 0x01;
46static constexpr size_t FRAME_HEADER_SIZE = 3;
47static constexpr size_t MAC_SIZE = 16;
48static constexpr size_t MAX_HANDSHAKE_SIZE = 128;
49static constexpr uint8_t HANDSHAKE_STATUS_OK = 0x00;
50static constexpr uint8_t HANDSHAKE_STATUS_REJECT = 0x01;
51
52inline void write_frame_header(uint8_t *buf, uint16_t payload_len) {
53 buf[0] = FRAME_INDICATOR;
54 buf[1] = (uint8_t) (payload_len >> 8);
55 buf[2] = (uint8_t) payload_len;
56}
57
61size_t format_reject_payload(uint8_t *buf, size_t capacity, const LogString *reason);
62
65const LogString *reject_reason_for(int err);
66
71static constexpr size_t MAC_FAILURE_PAYLOAD_SIZE = sizeof("Handshake MAC failure");
72
73} // namespace esphome::noise
74#endif // USE_NOISE
void set_psk(const uint8_t *psk)
psk points at 32 bytes that outlive the context (PROGMEM or caller owned RAM); nullptr means no key.
Definition noise.h:29
static bool is_all_zeros(const psk_t &psk)
Definition noise.h:19
void load_psk(psk_t &out) const
Copy the key out (flash-aware on ESP8266); all zeros when none is set.
Definition noise.cpp:19
const uint8_t * psk_
Definition noise.h:35
void write_frame_header(uint8_t *buf, uint16_t payload_len)
Definition noise.h:52
std::array< uint8_t, 32 > psk_t
Definition noise.h:11
const LogString * noise_err_to_logstr(int err)
Convert a noise error code to a readable error.
Definition noise.cpp:27
size_t format_reject_payload(uint8_t *buf, size_t capacity, const LogString *reason)
Fill buf with a handshake reject payload (status byte plus the reason text, PROGMEM aware); returns t...
Definition noise.cpp:69
const LogString * reject_reason_for(int err)
Reject reason for a failed handshake read.
Definition noise.cpp:65
uint16_t uint16_t & capacity
Definition helpers.cpp:25