From 5747c736c26a37043665b54e9664a25bd2b36ef0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 7 Sep 2026 12:21:04 +0200 Subject: [PATCH] [noise] Inline the spare slot check, keep the slot empty if the base multiply fails has_spare_ephemeral() is polled every api loop tick, so the flag is now an extern and the accessor lives in the header. --- esphome/components/noise/noise.cpp | 9 +++++---- esphome/components/noise/noise.h | 4 +++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/esphome/components/noise/noise.cpp b/esphome/components/noise/noise.cpp index 53a012f975..b2c6a3af8b 100644 --- a/esphome/components/noise/noise.cpp +++ b/esphome/components/noise/noise.cpp @@ -28,9 +28,7 @@ void NoiseContext::load_psk(psk_t &out) const { #ifdef USE_API_NOISE static uint8_t spare_ephemeral[EPHEMERAL_KEYPAIR_SIZE]; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) -static bool spare_ephemeral_ready = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) - -bool has_spare_ephemeral() { return spare_ephemeral_ready; } +bool spare_ephemeral_ready = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) void prepare_spare_ephemeral() { // A partial fill must never look ready @@ -44,7 +42,10 @@ void prepare_spare_ephemeral() { } private_key[0] &= 0xF8; private_key[EPHEMERAL_PRIVATE_KEY_SIZE - 1] = (private_key[EPHEMERAL_PRIVATE_KEY_SIZE - 1] & 0x7F) | 0x40; - crypto_scalarmult_curve25519_base(public_key, private_key); + if (crypto_scalarmult_curve25519_base(public_key, private_key) != 0) { + sodium_memzero(spare_ephemeral, EPHEMERAL_KEYPAIR_SIZE); + return; + } spare_ephemeral_ready = true; } diff --git a/esphome/components/noise/noise.h b/esphome/components/noise/noise.h index b30695f787..ca103275ba 100644 --- a/esphome/components/noise/noise.h +++ b/esphome/components/noise/noise.h @@ -48,7 +48,9 @@ using ephemeral_keypair_t = std::array; // One responder ephemeral key pair generated ahead of time (about 60 ms on // ESP8266), refilled by the api server while idle, shared by every noise // transport; an empty slot means the handshake generates its own key. -bool has_spare_ephemeral(); +extern bool spare_ephemeral_ready; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +// Polled every api loop tick, so it must inline +inline bool has_spare_ephemeral() { return spare_ephemeral_ready; } /// Fill the slot; blocks for the base point multiply void prepare_spare_ephemeral(); /// Move the slot into out and empty it; false (out untouched) when empty