Compare commits

...

3 Commits

4 changed files with 40 additions and 15 deletions

1
Cargo.lock generated
View File

@ -1766,6 +1766,7 @@ dependencies = [
"embassy-time", "embassy-time",
"embedded-io-async", "embedded-io-async",
"embedded-storage", "embedded-storage",
"embedded-tls",
"git-version", "git-version",
"heapless 0.7.16", "heapless 0.7.16",
"nourl", "nourl",

View File

@ -85,6 +85,10 @@ reqwless = { version = "0.5.0", features = ["defmt"] }
embedded-storage = "0.3.0" embedded-storage = "0.3.0"
const_format = "0.2.31" const_format = "0.2.31"
git-version = "0.3.5" git-version = "0.3.5"
embedded-tls = { version = "0.15.0", default-features = false, features = [
"async",
"defmt",
] }
[patch.crates-io] [patch.crates-io]
embassy-executor = { git = "https://github.com/embassy-rs/embassy" } embassy-executor = { git = "https://github.com/embassy-rs/embassy" }

View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
mkdir -p target/firmware mkdir -p target/firmware
cargo objcopy --release --features=exclude_firmwares -- -O binary target/firmware/firmware cargo objcopy --release -- -O binary target/firmware/firmware
shasum -a 512 -b target/firmware/firmware | dd ibs=128 count=1 | xxd -p -r > target/firmware/checksum shasum -a 512 -b target/firmware/firmware | dd ibs=128 count=1 | xxd -p -r > target/firmware/checksum
signify -S -m target/firmware/checksum -s ~/Projects/crypt/R0/private/keys/firmware/pico_p1.sec -x target/firmware/checksum.sig signify -S -m target/firmware/checksum -s ~/Projects/crypt/R0/private/keys/firmware/pico_p1.sec -x target/firmware/checksum.sig
tail -n1 target/firmware/checksum.sig | base64 -d -i | dd ibs=10 skip=1 > target/firmware/signed tail -n1 target/firmware/checksum.sig | base64 -d -i | dd ibs=10 skip=1 > target/firmware/signed

View File

@ -6,6 +6,7 @@ use core::cell::RefCell;
use embassy_boot_rp::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterConfig}; use embassy_boot_rp::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterConfig};
use embedded_storage::nor_flash::NorFlash; use embedded_storage::nor_flash::NorFlash;
use embedded_tls::{Aes128GcmSha256, NoVerify, TlsConfig, TlsConnection, TlsContext};
use heapless::{String, Vec}; use heapless::{String, Vec};
use rand::{ use rand::{
rngs::{SmallRng, StdRng}, rngs::{SmallRng, StdRng},
@ -88,6 +89,7 @@ enum Status<'a> {
PreparingUpdate, PreparingUpdate,
Erasing, Erasing,
Writing { progress: u32 }, Writing { progress: u32 },
Verifying,
UpdateComplete, UpdateComplete,
} }
@ -250,8 +252,7 @@ async fn main(spawner: Spawner) {
// Use the Ring Oscillator of the RP2040 as a source of true randomness to seed the // Use the Ring Oscillator of the RP2040 as a source of true randomness to seed the
// cryptographically secure PRNG // cryptographically secure PRNG
let mut rng_rosc = RoscRng; let mut rng = StdRng::from_rng(&mut RoscRng).unwrap();
let mut rng = StdRng::from_rng(&mut rng_rosc).unwrap();
let stack = make_static!(Stack::new( let stack = make_static!(Stack::new(
net_device, net_device,
@ -280,7 +281,7 @@ async fn main(spawner: Spawner) {
info!("IP Address: {}", cfg.address.address()); info!("IP Address: {}", cfg.address.address());
let mut rx_buffer = [0; 1024]; let mut rx_buffer = [0; 1024];
let mut tx_buffer = [0; 4096]; let mut tx_buffer = [0; 1024];
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
// socket.set_timeout(Some(Duration::from_secs(10))); // socket.set_timeout(Some(Duration::from_secs(10)));
@ -300,7 +301,7 @@ async fn main(spawner: Spawner) {
MqttVersion::MQTTv5, MqttVersion::MQTTv5,
// Use fast and simple PRNG to generate packet identifiers, there is no need for this to be // Use fast and simple PRNG to generate packet identifiers, there is no need for this to be
// cryptographically secure // cryptographically secure
SmallRng::from_rng(&mut rng_rosc).unwrap(), SmallRng::from_rng(&mut RoscRng).unwrap(),
); );
config.add_username(env!("MQTT_USERNAME")); config.add_username(env!("MQTT_USERNAME"));
@ -312,7 +313,7 @@ async fn main(spawner: Spawner) {
config.add_will(TOPIC_STATUS, &msg, true); config.add_will(TOPIC_STATUS, &msg, true);
let mut recv_buffer = [0; 1024]; let mut recv_buffer = [0; 1024];
let mut write_buffer = [0; 4096]; let mut write_buffer = [0; 1024];
let mut client = let mut client =
MqttClient::<_, 5, _>::new(socket, &mut write_buffer, &mut recv_buffer, config); MqttClient::<_, 5, _>::new(socket, &mut write_buffer, &mut recv_buffer, config);
@ -387,7 +388,7 @@ async fn main(spawner: Spawner) {
let url = message.get_url(); let url = message.get_url();
let url = Url::parse(url.as_str()).unwrap(); let url = Url::parse(url.as_str()).unwrap();
attempt_update(stack, &mut updater, &mut client, url).await; attempt_update(stack, &mut updater, &mut rng, &mut client, url).await;
} }
} }
} }
@ -411,6 +412,7 @@ const FLASH_SIZE: usize = 2 * 1024 * 1024;
async fn attempt_update<T, const MAX_PROPERTIES: usize, R, F>( async fn attempt_update<T, const MAX_PROPERTIES: usize, R, F>(
stack: &'static Stack<cyw43::NetDriver<'static>>, stack: &'static Stack<cyw43::NetDriver<'static>>,
updater: &mut BlockingFirmwareUpdater<'_, F, F>, updater: &mut BlockingFirmwareUpdater<'_, F, F>,
rng: &mut StdRng,
client: &mut MqttClient<'_, T, MAX_PROPERTIES, R>, client: &mut MqttClient<'_, T, MAX_PROPERTIES, R>,
url: Url<'_>, url: Url<'_>,
) where ) where
@ -427,23 +429,33 @@ async fn attempt_update<T, const MAX_PROPERTIES: usize, R, F>(
let ip = stack.dns_query(url.host(), DnsQueryType::A).await.unwrap()[0]; let ip = stack.dns_query(url.host(), DnsQueryType::A).await.unwrap()[0];
let mut rx_buffer = [0; 4096 * 2]; let mut rx_buffer = [0; 1024];
let mut tx_buffer = [0; 1024]; let mut tx_buffer = [0; 1024];
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
let addr = (ip, url.port_or_default()); let addr = (ip, url.port_or_default());
debug!("Addr: {}", addr); debug!("Addr: {}", addr);
socket.connect(addr).await.unwrap(); socket.connect(addr).await.unwrap();
debug!("Path: {}", url.path()); let mut read_record_buffer = [0; 16384 * 2];
Request::get(url.path()) let mut write_record_buffer = [0; 16384];
.build() let mut tls: TlsConnection<TcpSocket, Aes128GcmSha256> =
.write(&mut socket) TlsConnection::new(socket, &mut read_record_buffer, &mut write_record_buffer);
tls.open::<_, NoVerify>(TlsContext::new(&TlsConfig::new(), rng))
.await .await
.unwrap(); .unwrap();
let mut headers = [0; 4096]; debug!("Path: {}", url.path());
let resp = Response::read(&mut socket, Method::GET, &mut headers) Request::get(url.path())
.host(url.host())
.build()
.write(&mut tls)
.await
.unwrap();
let mut headers = [0; 1024];
let resp = Response::read(&mut tls, Method::GET, &mut headers)
.await .await
.unwrap(); .unwrap();
@ -492,7 +504,15 @@ async fn attempt_update<T, const MAX_PROPERTIES: usize, R, F>(
} }
debug!("Total size: {}", size); debug!("Total size: {}", size);
updater.verify_and_mark_updated(PUBLIC_SIGNING_KEY, &signature, size).unwrap(); let status = Status::Verifying.vec();
client
.send_message(TOPIC_STATUS, &status, QualityOfService::QoS1, false)
.await
.unwrap();
updater
.verify_and_mark_updated(PUBLIC_SIGNING_KEY, &signature, size)
.unwrap();
// Update mqtt message should be send using retain // Update mqtt message should be send using retain
// TODO: Clear the message // TODO: Clear the message