commit a3edd49f1039b0f27e676ffaf240816e4fca70df
parent cc9bf7897cdd8653b897d83c6bbae9383d43e3ec
Author: Daniel Barlow <dan@telent.net>
Date: Wed, 21 Jan 2026 21:42:26 +0000
check signature on each block
Diffstat:
1 file changed, 29 insertions(+), 18 deletions(-)
diff --git a/ecu-esp32/src/wifi.rs b/ecu-esp32/src/wifi.rs
@@ -7,6 +7,8 @@ use alloc::vec::Vec;
use alloc::string::String;
use alloc::format;
+use ed25519_dalek::{VerifyingKey, Verifier, Signature};
+
use embassy_executor::Spawner;
use embassy_net::{
Runner,
@@ -243,6 +245,7 @@ async fn write_ota(ota : &mut Ota<FlashStorage<'_>>,
sock: &mut embassy_net::tcp::TcpSocket<'_>) {
let mut buf = [0u8; ERASE_BLOCK_BYTES + ED25519_SIGNATURE_BYTES];
let mut buf_offset = 0;
+ let mut signed = true;
let len = {
let mut len_bytes = [0u8; 4];
@@ -253,13 +256,15 @@ async fn write_ota(ota : &mut Ota<FlashStorage<'_>>,
}
};
+ let verifying_key_bytes = include_bytes!("../../pubkey.bin");
+ let verifying_key: VerifyingKey = VerifyingKey::from_bytes(verifying_key_bytes).expect("verify");
+
info!("ota length {}", len);
if let Err(e) = ota.ota_begin(len, 0) {
error!("ota_begin failed {:?}", e);
return;
};
-
let mut remaining = len;
while remaining > 0 {
// info!("remaining {}, offset {}", remaining, buf_offset);
@@ -278,27 +283,33 @@ async fn write_ota(ota : &mut Ota<FlashStorage<'_>>,
break;
}
}
- if buf_offset == ED25519_SIGNATURE_BYTES + ERASE_BLOCK_BYTES {
- if let Err(_) = ota.ota_write_chunk(&buf[ED25519_SIGNATURE_BYTES..]) {
- break;
- }
- buf_offset = 0;
- };
- if remaining <= 0 {
- if let Err(_) = ota.ota_write_chunk(&buf[ED25519_SIGNATURE_BYTES..buf_offset]) {
- break;
- }
- };
+
+ if remaining <= 0 || buf_offset == ED25519_SIGNATURE_BYTES + ERASE_BLOCK_BYTES {
+ let (sig, chunk) = buf.split_at(ED25519_SIGNATURE_BYTES);
+ let signature: Signature = Signature::try_from(sig).expect("sig");
+ signed = signed && verifying_key.verify(chunk, &signature).is_ok();
+
+ if signed {
+ if let Err(_) = ota.ota_write_chunk(&buf[ED25519_SIGNATURE_BYTES..buf_offset]) {
+ break;
+ }
+ } else {
+ // accept the rest of the update, just don't flash it.
+ warn!("signature invalid with {remaining} left");
+ }
+ buf_offset = 0;
+ }
}
if remaining == 0 {
info!("wrote all bytes");
- if ota.ota_flush(false, false).is_ok() { // ignore crc, no rollback
- info!("write {:?}", sock.write(b"BYE\n").await);
- let _ = sock.flush().await;
- sock.close();
- Timer::after_millis(1000).await;
- esp_hal::system::software_reset();
+ info!("write {:?}", sock.write(b"BYE\n").await);
+ let _ = sock.flush().await;
+ sock.close();
+ if signed && !ota.ota_flush(false, false).is_ok() {
+ error!("ota failed");
}
+ Timer::after_millis(1000).await;
+ esp_hal::system::software_reset();
} else {
warn!("stream ended early or flash failed with {} bytes left", remaining);
}