ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
api_frame_helper_noise.h
Go to the documentation of this file.
1#pragma once
2#include "api_frame_helper.h"
3#ifdef USE_API
4#ifdef USE_API_NOISE
5#include "noise/protocol.h"
7
8namespace esphome::api {
9
10class APINoiseFrameHelper final : public APIFrameHelper {
11 public:
12 // Noise header structure:
13 // Pos 0: indicator (0x01)
14 // Pos 1-2: encrypted payload size (16-bit big-endian)
15 // Pos 3-6: encrypted type (16-bit) + data_len (16-bit)
16 // Pos 7+: actual payload data
17 static constexpr uint8_t HEADER_PADDING = noise::FRAME_HEADER_SIZE + 2 + 2; // frame header + type + data_len
18
19 APINoiseFrameHelper(std::unique_ptr<socket::Socket> socket, noise::NoiseContext &ctx)
20 : APIFrameHelper(std::move(socket)), ctx_(ctx) {
22 }
23 ~APINoiseFrameHelper() override;
24 APIError init() override;
25#ifdef USE_API_PLAINTEXT
26 // Take over a connection whose first bytes were consumed by a plaintext
27 // helper on an unprovisioned device (see APIError::PROTOCOL_SWITCH_TO_NOISE).
28 // Seeds the already-read header bytes and pumps the handshake state machine
29 // until it would block.
30 APIError init_from_handoff(const uint8_t *header, uint8_t header_len);
31#endif
32#ifdef USE_API_OUTGOING_CONNECTION
33 // Send the server hello immediately so the peer can pick the key before
34 // its PSK-mixed message. Call after init(); the mode is tracked in state_
35 // so the helper does not grow.
37#endif
38 APIError loop() override;
41 APIError write_protobuf_messages(ProtoWriteBuffer buffer, std::span<const MessageInfo> messages) override;
42
43 protected:
54 APIError write_frame_(const uint8_t *data, uint16_t len);
55 APIError encrypt_noise_message_(uint8_t *buf_start, uint16_t payload_size, uint16_t message_type,
56 uint16_t &encrypted_len_out);
59 void send_explicit_handshake_reject_(const LogString *reason);
61 APIError handle_noise_error_(int err, const LogString *func_name, APIError api_err);
62
63 // Pointers first (4 bytes each; the handshake wrapper holds one pointer)
65 NoiseCipherState *send_cipher_{nullptr};
66 NoiseCipherState *recv_cipher_{nullptr};
67
68 // Reference to noise context (4 bytes on 32-bit)
70
71 // Buffer for noise handshake prologue (released after handshake)
73
74 // Group small types together
75 // Fixed-size header buffer for noise protocol:
76 // 1 byte for indicator + 2 bytes for message size (16-bit value, not varint)
77 // Note: Maximum message size is UINT16_MAX (65535), with a limit of 128 bytes during handshake phase
78 uint8_t rx_header_buf_[noise::FRAME_HEADER_SIZE];
79 uint8_t rx_header_buf_len_ = 0;
80 // 4 bytes total, no padding
81};
82
83} // namespace esphome::api
84#endif // USE_API_NOISE
85#endif // USE_API
Byte buffer that skips zero-initialization on resize().
Definition api_buffer.h:26
APIError write_protobuf_packet(uint16_t type, ProtoWriteBuffer buffer) override
APIError encrypt_noise_message_(uint8_t *buf_start, uint16_t payload_size, uint16_t message_type, uint16_t &encrypted_len_out)
APIError pump_handshake_()
Drive the handshake state machine until DATA, WOULD_BLOCK, or a fatal error.
APINoiseFrameHelper(std::unique_ptr< socket::Socket > socket, noise::NoiseContext &ctx)
APIError read_packet(ReadPacketBuffer *buffer) override
uint8_t rx_header_buf_[noise::FRAME_HEADER_SIZE]
APIError handle_noise_error_(int err, const LogString *func_name, APIError api_err)
APIError write_protobuf_messages(ProtoWriteBuffer buffer, std::span< const MessageInfo > messages) override
APIError state_action_()
To be called from read/write methods.
APIError try_read_frame_()
Read a packet into the rx_buf_.
APIError loop() override
Run through handshake messages (if in that phase)
APIError handle_handshake_frame_error_(APIError aerr)
void send_explicit_handshake_reject_(const LogString *reason)
APIError write_frame_(const uint8_t *data, uint16_t len)
APIError init() override
Initialize the frame helper, returns OK if successful.
APIError init_handshake_()
Initiate the data structures for the handshake.
APIError init_from_handoff(const uint8_t *header, uint8_t header_len)
noise::NoiseResponderHandshake handshake_
Sans-IO responder side of a Noise_NNpsk0_25519_ChaChaPoly_SHA256 handshake.
uint8_t type
uint32_t buffer
Definition gif.cpp:50
const void size_t len
Definition hal.h:68
STL namespace.
uint32_t payload_size()