1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-31 07:03:55 +00:00
This commit is contained in:
J. Nick Koston
2025-07-19 15:18:43 -10:00
parent 0046e67727
commit 722df19758
2 changed files with 38 additions and 43 deletions

View File

@@ -312,6 +312,16 @@ APIError APINoiseFrameHelper::handle_handshake_frame_error_(APIError aerr) {
return aerr; return aerr;
} }
// Helper for handling noise library errors
APIError APINoiseFrameHelper::handle_noise_error_(int err, const char *func_name, APIError api_err) {
if (err != 0) {
state_ = State::FAILED;
HELPER_LOG("%s failed: %s", func_name, noise_err_to_str(err).c_str());
return api_err;
}
return APIError::OK;
}
/// Run through handshake messages (if in that phase) /// Run through handshake messages (if in that phase)
APIError APINoiseFrameHelper::loop() { APIError APINoiseFrameHelper::loop() {
// During handshake phase, process as many actions as possible until we can't progress // During handshake phase, process as many actions as possible until we can't progress
@@ -502,14 +512,13 @@ APIError APINoiseFrameHelper::state_action_() {
noise_buffer_set_input(mbuf, frame.msg.data() + 1, frame.msg.size() - 1); noise_buffer_set_input(mbuf, frame.msg.data() + 1, frame.msg.size() - 1);
err = noise_handshakestate_read_message(handshake_, &mbuf, nullptr); err = noise_handshakestate_read_message(handshake_, &mbuf, nullptr);
if (err != 0) { if (err != 0) {
state_ = State::FAILED; // Special handling for MAC failure
HELPER_LOG("noise_handshakestate_read_message failed: %s", noise_err_to_str(err).c_str());
if (err == NOISE_ERROR_MAC_FAILURE) { if (err == NOISE_ERROR_MAC_FAILURE) {
send_explicit_handshake_reject_("Handshake MAC failure"); send_explicit_handshake_reject_("Handshake MAC failure");
} else { } else {
send_explicit_handshake_reject_("Handshake error"); send_explicit_handshake_reject_("Handshake error");
} }
return APIError::HANDSHAKESTATE_READ_FAILED; return handle_noise_error_(err, "noise_handshakestate_read_message", APIError::HANDSHAKESTATE_READ_FAILED);
} }
aerr = check_handshake_finished_(); aerr = check_handshake_finished_();
@@ -522,11 +531,10 @@ APIError APINoiseFrameHelper::state_action_() {
noise_buffer_set_output(mbuf, buffer + 1, sizeof(buffer) - 1); noise_buffer_set_output(mbuf, buffer + 1, sizeof(buffer) - 1);
err = noise_handshakestate_write_message(handshake_, &mbuf, nullptr); err = noise_handshakestate_write_message(handshake_, &mbuf, nullptr);
if (err != 0) { APIError aerr_write =
state_ = State::FAILED; handle_noise_error_(err, "noise_handshakestate_write_message", APIError::HANDSHAKESTATE_WRITE_FAILED);
HELPER_LOG("noise_handshakestate_write_message failed: %s", noise_err_to_str(err).c_str()); if (aerr_write != APIError::OK)
return APIError::HANDSHAKESTATE_WRITE_FAILED; return aerr_write;
}
buffer[0] = 0x00; // success buffer[0] = 0x00; // success
aerr = write_frame_(buffer, mbuf.size + 1); aerr = write_frame_(buffer, mbuf.size + 1);
@@ -584,11 +592,9 @@ APIError APINoiseFrameHelper::read_packet(ReadPacketBuffer *buffer) {
noise_buffer_init(mbuf); noise_buffer_init(mbuf);
noise_buffer_set_inout(mbuf, frame.msg.data(), frame.msg.size(), frame.msg.size()); noise_buffer_set_inout(mbuf, frame.msg.data(), frame.msg.size(), frame.msg.size());
err = noise_cipherstate_decrypt(recv_cipher_, &mbuf); err = noise_cipherstate_decrypt(recv_cipher_, &mbuf);
if (err != 0) { APIError decrypt_err = handle_noise_error_(err, "noise_cipherstate_decrypt", APIError::CIPHERSTATE_DECRYPT_FAILED);
state_ = State::FAILED; if (decrypt_err != APIError::OK)
HELPER_LOG("noise_cipherstate_decrypt failed: %s", noise_err_to_str(err).c_str()); return decrypt_err;
return APIError::CIPHERSTATE_DECRYPT_FAILED;
}
uint16_t msg_size = mbuf.size; uint16_t msg_size = mbuf.size;
uint8_t *msg_data = frame.msg.data(); uint8_t *msg_data = frame.msg.data();
@@ -667,11 +673,9 @@ APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, st
4 + packet.payload_size + frame_footer_size_); 4 + packet.payload_size + frame_footer_size_);
int err = noise_cipherstate_encrypt(send_cipher_, &mbuf); int err = noise_cipherstate_encrypt(send_cipher_, &mbuf);
if (err != 0) { APIError aerr = handle_noise_error_(err, "noise_cipherstate_encrypt", APIError::CIPHERSTATE_ENCRYPT_FAILED);
state_ = State::FAILED; if (aerr != APIError::OK)
HELPER_LOG("noise_cipherstate_encrypt failed: %s", noise_err_to_str(err).c_str()); return aerr;
return APIError::CIPHERSTATE_ENCRYPT_FAILED;
}
// Fill in the encrypted size // Fill in the encrypted size
buf_start[1] = static_cast<uint8_t>(mbuf.size >> 8); buf_start[1] = static_cast<uint8_t>(mbuf.size >> 8);
@@ -722,35 +726,27 @@ APIError APINoiseFrameHelper::init_handshake_() {
nid_.modifier_ids[0] = NOISE_MODIFIER_PSK0; nid_.modifier_ids[0] = NOISE_MODIFIER_PSK0;
err = noise_handshakestate_new_by_id(&handshake_, &nid_, NOISE_ROLE_RESPONDER); err = noise_handshakestate_new_by_id(&handshake_, &nid_, NOISE_ROLE_RESPONDER);
if (err != 0) { APIError aerr = handle_noise_error_(err, "noise_handshakestate_new_by_id", APIError::HANDSHAKESTATE_SETUP_FAILED);
state_ = State::FAILED; if (aerr != APIError::OK)
HELPER_LOG("noise_handshakestate_new_by_id failed: %s", noise_err_to_str(err).c_str()); return aerr;
return APIError::HANDSHAKESTATE_SETUP_FAILED;
}
const auto &psk = ctx_->get_psk(); const auto &psk = ctx_->get_psk();
err = noise_handshakestate_set_pre_shared_key(handshake_, psk.data(), psk.size()); err = noise_handshakestate_set_pre_shared_key(handshake_, psk.data(), psk.size());
if (err != 0) { aerr = handle_noise_error_(err, "noise_handshakestate_set_pre_shared_key", APIError::HANDSHAKESTATE_SETUP_FAILED);
state_ = State::FAILED; if (aerr != APIError::OK)
HELPER_LOG("noise_handshakestate_set_pre_shared_key failed: %s", noise_err_to_str(err).c_str()); return aerr;
return APIError::HANDSHAKESTATE_SETUP_FAILED;
}
err = noise_handshakestate_set_prologue(handshake_, prologue_.data(), prologue_.size()); err = noise_handshakestate_set_prologue(handshake_, prologue_.data(), prologue_.size());
if (err != 0) { aerr = handle_noise_error_(err, "noise_handshakestate_set_prologue", APIError::HANDSHAKESTATE_SETUP_FAILED);
state_ = State::FAILED; if (aerr != APIError::OK)
HELPER_LOG("noise_handshakestate_set_prologue failed: %s", noise_err_to_str(err).c_str()); return aerr;
return APIError::HANDSHAKESTATE_SETUP_FAILED;
}
// set_prologue copies it into handshakestate, so we can get rid of it now // set_prologue copies it into handshakestate, so we can get rid of it now
prologue_ = {}; prologue_ = {};
err = noise_handshakestate_start(handshake_); err = noise_handshakestate_start(handshake_);
if (err != 0) { aerr = handle_noise_error_(err, "noise_handshakestate_start", APIError::HANDSHAKESTATE_SETUP_FAILED);
state_ = State::FAILED; if (aerr != APIError::OK)
HELPER_LOG("noise_handshakestate_start failed: %s", noise_err_to_str(err).c_str()); return aerr;
return APIError::HANDSHAKESTATE_SETUP_FAILED;
}
return APIError::OK; return APIError::OK;
} }
@@ -766,11 +762,9 @@ APIError APINoiseFrameHelper::check_handshake_finished_() {
return APIError::HANDSHAKESTATE_BAD_STATE; return APIError::HANDSHAKESTATE_BAD_STATE;
} }
int err = noise_handshakestate_split(handshake_, &send_cipher_, &recv_cipher_); int err = noise_handshakestate_split(handshake_, &send_cipher_, &recv_cipher_);
if (err != 0) { APIError aerr = handle_noise_error_(err, "noise_handshakestate_split", APIError::HANDSHAKESTATE_SPLIT_FAILED);
state_ = State::FAILED; if (aerr != APIError::OK)
HELPER_LOG("noise_handshakestate_split failed: %s", noise_err_to_str(err).c_str()); return aerr;
return APIError::HANDSHAKESTATE_SPLIT_FAILED;
}
frame_footer_size_ = noise_cipherstate_get_mac_length(send_cipher_); frame_footer_size_ = noise_cipherstate_get_mac_length(send_cipher_);

View File

@@ -213,6 +213,7 @@ class APINoiseFrameHelper : public APIFrameHelper {
APIError check_handshake_finished_(); APIError check_handshake_finished_();
void send_explicit_handshake_reject_(const std::string &reason); void send_explicit_handshake_reject_(const std::string &reason);
APIError handle_handshake_frame_error_(APIError aerr); APIError handle_handshake_frame_error_(APIError aerr);
APIError handle_noise_error_(int err, const char *func_name, APIError api_err);
// Pointers first (4 bytes each) // Pointers first (4 bytes each)
NoiseHandshakeState *handshake_{nullptr}; NoiseHandshakeState *handshake_{nullptr};