From 8aaffe82e71dfb2b3845c95bbf59ef4a34c7096c Mon Sep 17 00:00:00 2001
From: Rasmus Melchior Jacobsen <rmja@laesoe.org>
Date: Mon, 3 Apr 2023 14:59:55 +0200
Subject: [PATCH 1/4] Add incremental hash to FirmwareUpdater

This adds support for computing any hash over the update in the dtu area by providing a closure to the hash update function.
---
 embassy-boot/boot/src/firmware_updater.rs | 67 ++++++++++++++---------
 embassy-boot/boot/src/lib.rs              |  2 +-
 2 files changed, 43 insertions(+), 26 deletions(-)

diff --git a/embassy-boot/boot/src/firmware_updater.rs b/embassy-boot/boot/src/firmware_updater.rs
index af1ba114a..90157036a 100644
--- a/embassy-boot/boot/src/firmware_updater.rs
+++ b/embassy-boot/boot/src/firmware_updater.rs
@@ -118,13 +118,13 @@ impl FirmwareUpdater {
         _state_and_dfu_flash: &mut F,
         _public_key: &[u8],
         _signature: &[u8],
-        _update_len: usize,
+        _update_len: u32,
         _aligned: &mut [u8],
     ) -> Result<(), FirmwareUpdaterError> {
         let _read_size = _aligned.len();
 
         assert_eq!(_aligned.len(), F::WRITE_SIZE);
-        assert!(_update_len <= self.dfu.len());
+        assert!(_update_len <= self.dfu.len() as u32);
 
         #[cfg(feature = "ed25519-dalek")]
         {
@@ -136,11 +136,8 @@ impl FirmwareUpdater {
             let signature = Signature::from_bytes(_signature).map_err(into_signature_error)?;
 
             let mut digest = Sha512::new();
-            for offset in (0.._update_len).step_by(_aligned.len()) {
-                self.dfu.read(_state_and_dfu_flash, offset as u32, _aligned).await?;
-                let len = core::cmp::min(_update_len - offset, _aligned.len());
-                digest.update(&_aligned[..len]);
-            }
+            self.incremental_hash(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))
+                .await?;
 
             public_key
                 .verify(&digest.finalize(), &signature)
@@ -161,11 +158,8 @@ impl FirmwareUpdater {
             let signature = Signature::try_from(&signature).map_err(into_signature_error)?;
 
             let mut digest = Sha512::new();
-            for offset in (0.._update_len).step_by(_aligned.len()) {
-                self.dfu.read(_state_and_dfu_flash, offset as u32, _aligned).await?;
-                let len = core::cmp::min(_update_len - offset, _aligned.len());
-                digest.update(&_aligned[..len]);
-            }
+            self.incremental_hash(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))
+                .await?;
 
             let message = digest.finalize();
             let r = public_key.verify(&message, &signature);
@@ -182,6 +176,22 @@ impl FirmwareUpdater {
         self.set_magic(_aligned, SWAP_MAGIC, _state_and_dfu_flash).await
     }
 
+    /// Iterate through the DFU and process all bytes with the provided closure.
+    pub async fn incremental_hash<F: AsyncNorFlash>(
+        &mut self,
+        dfu_flash: &mut F,
+        update_len: u32,
+        aligned: &mut [u8],
+        mut update: impl FnMut(&[u8]),
+    ) -> Result<(), FirmwareUpdaterError> {
+        for offset in (0..update_len).step_by(aligned.len()) {
+            self.dfu.read(dfu_flash, offset, aligned).await?;
+            let len = core::cmp::min((update_len - offset) as usize, aligned.len());
+            update(&aligned[..len]);
+        }
+        Ok(())
+    }
+
     /// Mark to trigger firmware swap on next boot.
     ///
     /// # Safety
@@ -317,14 +327,13 @@ impl FirmwareUpdater {
         _state_and_dfu_flash: &mut F,
         _public_key: &[u8],
         _signature: &[u8],
-        _update_len: usize,
+        _update_len: u32,
         _aligned: &mut [u8],
     ) -> Result<(), FirmwareUpdaterError> {
-        let _end = self.dfu.from + _update_len;
         let _read_size = _aligned.len();
 
         assert_eq!(_aligned.len(), F::WRITE_SIZE);
-        assert!(_end <= self.dfu.to);
+        assert!(_update_len <= self.dfu.len() as u32);
 
         #[cfg(feature = "ed25519-dalek")]
         {
@@ -336,11 +345,7 @@ impl FirmwareUpdater {
             let signature = Signature::from_bytes(_signature).map_err(into_signature_error)?;
 
             let mut digest = Sha512::new();
-            for offset in (0.._update_len).step_by(_aligned.len()) {
-                self.dfu.read_blocking(_state_and_dfu_flash, offset as u32, _aligned)?;
-                let len = core::cmp::min(_update_len - offset, _aligned.len());
-                digest.update(&_aligned[..len]);
-            }
+            self.incremental_hash_blocking(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))?;
 
             public_key
                 .verify(&digest.finalize(), &signature)
@@ -361,11 +366,7 @@ impl FirmwareUpdater {
             let signature = Signature::try_from(&signature).map_err(into_signature_error)?;
 
             let mut digest = Sha512::new();
-            for offset in (0.._update_len).step_by(_aligned.len()) {
-                self.dfu.read_blocking(_state_and_dfu_flash, offset as u32, _aligned)?;
-                let len = core::cmp::min(_update_len - offset, _aligned.len());
-                digest.update(&_aligned[..len]);
-            }
+            self.incremental_hash_blocking(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))?;
 
             let message = digest.finalize();
             let r = public_key.verify(&message, &signature);
@@ -382,6 +383,22 @@ impl FirmwareUpdater {
         self.set_magic_blocking(_aligned, SWAP_MAGIC, _state_and_dfu_flash)
     }
 
+    /// Iterate through the DFU and process all bytes with the provided closure.
+    pub fn incremental_hash_blocking<F: NorFlash>(
+        &mut self,
+        dfu_flash: &mut F,
+        update_len: u32,
+        aligned: &mut [u8],
+        mut update: impl FnMut(&[u8]),
+    ) -> Result<(), FirmwareUpdaterError> {
+        for offset in (0..update_len).step_by(aligned.len()) {
+            self.dfu.read_blocking(dfu_flash, offset, aligned)?;
+            let len = core::cmp::min((update_len - offset) as usize, aligned.len());
+            update(&aligned[..len]);
+        }
+        Ok(())
+    }
+
     /// Mark to trigger firmware swap on next boot.
     ///
     /// # Safety
diff --git a/embassy-boot/boot/src/lib.rs b/embassy-boot/boot/src/lib.rs
index 4c28d7aa4..6d0e2d8c2 100644
--- a/embassy-boot/boot/src/lib.rs
+++ b/embassy-boot/boot/src/lib.rs
@@ -308,7 +308,7 @@ mod tests {
             &mut flash,
             &public_key.to_bytes(),
             &signature.to_bytes(),
-            firmware_len,
+            firmware_len as u32,
             &mut aligned,
         ))
         .is_ok());

From 7c6936a2e398e43ea3dc89736dc385402822933f Mon Sep 17 00:00:00 2001
From: Rasmus Melchior Jacobsen <rmja@laesoe.org>
Date: Tue, 4 Apr 2023 12:24:30 +0200
Subject: [PATCH 2/4] Let hash functions take a digest::Digest trait

... and add adapters for current Sha512 implementations that does not inplement the Digest trait
---
 embassy-boot/boot/Cargo.toml                  |   4 +-
 .../boot/src/digest_adapters/ed25519_dalek.rs |  30 +++++
 embassy-boot/boot/src/digest_adapters/mod.rs  |   5 +
 .../boot/src/digest_adapters/salty.rs         |  29 +++++
 embassy-boot/boot/src/firmware_updater.rs     | 108 ++++++++++++------
 embassy-boot/boot/src/lib.rs                  |   1 +
 6 files changed, 140 insertions(+), 37 deletions(-)
 create mode 100644 embassy-boot/boot/src/digest_adapters/ed25519_dalek.rs
 create mode 100644 embassy-boot/boot/src/digest_adapters/mod.rs
 create mode 100644 embassy-boot/boot/src/digest_adapters/salty.rs

diff --git a/embassy-boot/boot/Cargo.toml b/embassy-boot/boot/Cargo.toml
index 3312c2f9f..c4ebdaff2 100644
--- a/embassy-boot/boot/Cargo.toml
+++ b/embassy-boot/boot/Cargo.toml
@@ -24,6 +24,7 @@ features = ["defmt"]
 
 [dependencies]
 defmt = { version = "0.3", optional = true }
+digest = "0.10"
 log = { version = "0.4", optional = true  }
 ed25519-dalek = { version = "1.0.1", default_features = false, features = ["u32_backend"], optional = true }
 embassy-sync = { version = "0.1.0", path = "../../embassy-sync" }
@@ -37,6 +38,7 @@ log = "0.4"
 env_logger = "0.9"
 rand = "0.7" # ed25519-dalek v1.0.1 depends on this exact version
 futures = { version = "0.3", features = ["executor"] }
+sha1 = "0.10.5"
 
 [dev-dependencies.ed25519-dalek]
 default_features = false
@@ -47,4 +49,4 @@ ed25519-dalek = ["dep:ed25519-dalek", "_verify"]
 ed25519-salty = ["dep:salty", "_verify"]
 
 #Internal features
-_verify = []
\ No newline at end of file
+_verify = []
diff --git a/embassy-boot/boot/src/digest_adapters/ed25519_dalek.rs b/embassy-boot/boot/src/digest_adapters/ed25519_dalek.rs
new file mode 100644
index 000000000..a184d1c51
--- /dev/null
+++ b/embassy-boot/boot/src/digest_adapters/ed25519_dalek.rs
@@ -0,0 +1,30 @@
+use digest::typenum::U64;
+use digest::{FixedOutput, HashMarker, OutputSizeUser, Update};
+use ed25519_dalek::Digest as _;
+
+pub struct Sha512(ed25519_dalek::Sha512);
+
+impl Default for Sha512 {
+    fn default() -> Self {
+        Self(ed25519_dalek::Sha512::new())
+    }
+}
+
+impl Update for Sha512 {
+    fn update(&mut self, data: &[u8]) {
+        self.0.update(data)
+    }
+}
+
+impl FixedOutput for Sha512 {
+    fn finalize_into(self, out: &mut digest::Output<Self>) {
+        let result = self.0.finalize();
+        out.as_mut_slice().copy_from_slice(result.as_slice())
+    }
+}
+
+impl OutputSizeUser for Sha512 {
+    type OutputSize = U64;
+}
+
+impl HashMarker for Sha512 {}
diff --git a/embassy-boot/boot/src/digest_adapters/mod.rs b/embassy-boot/boot/src/digest_adapters/mod.rs
new file mode 100644
index 000000000..9b4b4b60c
--- /dev/null
+++ b/embassy-boot/boot/src/digest_adapters/mod.rs
@@ -0,0 +1,5 @@
+#[cfg(feature = "ed25519-dalek")]
+pub(crate) mod ed25519_dalek;
+
+#[cfg(feature = "ed25519-salty")]
+pub(crate) mod salty;
diff --git a/embassy-boot/boot/src/digest_adapters/salty.rs b/embassy-boot/boot/src/digest_adapters/salty.rs
new file mode 100644
index 000000000..2b5dcf3af
--- /dev/null
+++ b/embassy-boot/boot/src/digest_adapters/salty.rs
@@ -0,0 +1,29 @@
+use digest::typenum::U64;
+use digest::{FixedOutput, HashMarker, OutputSizeUser, Update};
+
+pub struct Sha512(salty::Sha512);
+
+impl Default for Sha512 {
+    fn default() -> Self {
+        Self(salty::Sha512::new())
+    }
+}
+
+impl Update for Sha512 {
+    fn update(&mut self, data: &[u8]) {
+        self.0.update(data)
+    }
+}
+
+impl FixedOutput for Sha512 {
+    fn finalize_into(self, out: &mut digest::Output<Self>) {
+        let result = self.0.finalize();
+        out.as_mut_slice().copy_from_slice(result.as_slice())
+    }
+}
+
+impl OutputSizeUser for Sha512 {
+    type OutputSize = U64;
+}
+
+impl HashMarker for Sha512 {}
diff --git a/embassy-boot/boot/src/firmware_updater.rs b/embassy-boot/boot/src/firmware_updater.rs
index 22e3e6b00..2d1b26980 100644
--- a/embassy-boot/boot/src/firmware_updater.rs
+++ b/embassy-boot/boot/src/firmware_updater.rs
@@ -1,3 +1,4 @@
+use digest::Digest;
 use embedded_storage::nor_flash::{NorFlash, NorFlashError, NorFlashErrorKind};
 use embedded_storage_async::nor_flash::NorFlash as AsyncNorFlash;
 
@@ -128,25 +129,27 @@ impl FirmwareUpdater {
 
         #[cfg(feature = "ed25519-dalek")]
         {
-            use ed25519_dalek::{Digest, PublicKey, Sha512, Signature, SignatureError, Verifier};
+            use ed25519_dalek::{PublicKey, Signature, SignatureError, Verifier};
+
+            use crate::digest_adapters::ed25519_dalek::Sha512;
 
             let into_signature_error = |e: SignatureError| FirmwareUpdaterError::Signature(e.into());
 
             let public_key = PublicKey::from_bytes(_public_key).map_err(into_signature_error)?;
             let signature = Signature::from_bytes(_signature).map_err(into_signature_error)?;
 
-            let mut digest = Sha512::new();
-            self.incremental_hash(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))
+            let mut message = [0; 64];
+            self.hash::<_, Sha512>(_state_and_dfu_flash, _update_len, _aligned, &mut message)
                 .await?;
 
-            public_key
-                .verify(&digest.finalize(), &signature)
-                .map_err(into_signature_error)?
+            public_key.verify(&message, &signature).map_err(into_signature_error)?
         }
         #[cfg(feature = "ed25519-salty")]
         {
             use salty::constants::{PUBLICKEY_SERIALIZED_LENGTH, SIGNATURE_SERIALIZED_LENGTH};
-            use salty::{PublicKey, Sha512, Signature};
+            use salty::{PublicKey, Signature};
+
+            use crate::digest_adapters::salty::Sha512;
 
             fn into_signature_error<E>(_: E) -> FirmwareUpdaterError {
                 FirmwareUpdaterError::Signature(signature::Error::default())
@@ -157,11 +160,10 @@ impl FirmwareUpdater {
             let signature: [u8; SIGNATURE_SERIALIZED_LENGTH] = _signature.try_into().map_err(into_signature_error)?;
             let signature = Signature::try_from(&signature).map_err(into_signature_error)?;
 
-            let mut digest = Sha512::new();
-            self.incremental_hash(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))
+            let mut message = [0; 64];
+            self.hash::<_, Sha512>(_state_and_dfu_flash, _update_len, _aligned, &mut message)
                 .await?;
 
-            let message = digest.finalize();
             let r = public_key.verify(&message, &signature);
             trace!(
                 "Verifying with public key {}, signature {} and message {} yields ok: {}",
@@ -176,19 +178,21 @@ impl FirmwareUpdater {
         self.set_magic(_aligned, SWAP_MAGIC, _state_and_dfu_flash).await
     }
 
-    /// Iterate through the DFU and process all bytes with the provided closure.
-    pub async fn incremental_hash<F: AsyncNorFlash>(
+    /// Verify the update in DFU with any digest.
+    pub async fn hash<F: AsyncNorFlash, D: Digest>(
         &mut self,
         dfu_flash: &mut F,
         update_len: u32,
-        aligned: &mut [u8],
-        mut update: impl FnMut(&[u8]),
+        chunk_buf: &mut [u8],
+        output: &mut [u8],
     ) -> Result<(), FirmwareUpdaterError> {
-        for offset in (0..update_len).step_by(aligned.len()) {
-            self.dfu.read(dfu_flash, offset, aligned).await?;
-            let len = core::cmp::min((update_len - offset) as usize, aligned.len());
-            update(&aligned[..len]);
+        let mut digest = D::new();
+        for offset in (0..update_len).step_by(chunk_buf.len()) {
+            self.dfu.read(dfu_flash, offset, chunk_buf).await?;
+            let len = core::cmp::min((update_len - offset) as usize, chunk_buf.len());
+            digest.update(&chunk_buf[..len]);
         }
+        output.copy_from_slice(digest.finalize().as_slice());
         Ok(())
     }
 
@@ -334,24 +338,26 @@ impl FirmwareUpdater {
 
         #[cfg(feature = "ed25519-dalek")]
         {
-            use ed25519_dalek::{Digest, PublicKey, Sha512, Signature, SignatureError, Verifier};
+            use ed25519_dalek::{PublicKey, Signature, SignatureError, Verifier};
+
+            use crate::digest_adapters::ed25519_dalek::Sha512;
 
             let into_signature_error = |e: SignatureError| FirmwareUpdaterError::Signature(e.into());
 
             let public_key = PublicKey::from_bytes(_public_key).map_err(into_signature_error)?;
             let signature = Signature::from_bytes(_signature).map_err(into_signature_error)?;
 
-            let mut digest = Sha512::new();
-            self.incremental_hash_blocking(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))?;
+            let mut message = [0; 64];
+            self.hash_blocking::<_, Sha512>(_state_and_dfu_flash, _update_len, _aligned, &mut message)?;
 
-            public_key
-                .verify(&digest.finalize(), &signature)
-                .map_err(into_signature_error)?
+            public_key.verify(&message, &signature).map_err(into_signature_error)?
         }
         #[cfg(feature = "ed25519-salty")]
         {
             use salty::constants::{PUBLICKEY_SERIALIZED_LENGTH, SIGNATURE_SERIALIZED_LENGTH};
-            use salty::{PublicKey, Sha512, Signature};
+            use salty::{PublicKey, Signature};
+
+            use crate::digest_adapters::salty::Sha512;
 
             fn into_signature_error<E>(_: E) -> FirmwareUpdaterError {
                 FirmwareUpdaterError::Signature(signature::Error::default())
@@ -362,10 +368,9 @@ impl FirmwareUpdater {
             let signature: [u8; SIGNATURE_SERIALIZED_LENGTH] = _signature.try_into().map_err(into_signature_error)?;
             let signature = Signature::try_from(&signature).map_err(into_signature_error)?;
 
-            let mut digest = Sha512::new();
-            self.incremental_hash_blocking(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))?;
+            let mut message = [0; 64];
+            self.hash_blocking::<_, Sha512>(_state_and_dfu_flash, _update_len, _aligned, &mut message)?;
 
-            let message = digest.finalize();
             let r = public_key.verify(&message, &signature);
             trace!(
                 "Verifying with public key {}, signature {} and message {} yields ok: {}",
@@ -380,19 +385,21 @@ impl FirmwareUpdater {
         self.set_magic_blocking(_aligned, SWAP_MAGIC, _state_and_dfu_flash)
     }
 
-    /// Iterate through the DFU and process all bytes with the provided closure.
-    pub fn incremental_hash_blocking<F: NorFlash>(
+    /// Verify the update in DFU with any digest.
+    pub fn hash_blocking<F: NorFlash, D: Digest>(
         &mut self,
         dfu_flash: &mut F,
         update_len: u32,
-        aligned: &mut [u8],
-        mut update: impl FnMut(&[u8]),
+        chunk_buf: &mut [u8],
+        output: &mut [u8],
     ) -> Result<(), FirmwareUpdaterError> {
-        for offset in (0..update_len).step_by(aligned.len()) {
-            self.dfu.read_blocking(dfu_flash, offset, aligned)?;
-            let len = core::cmp::min((update_len - offset) as usize, aligned.len());
-            update(&aligned[..len]);
+        let mut digest = D::new();
+        for offset in (0..update_len).step_by(chunk_buf.len()) {
+            self.dfu.read_blocking(dfu_flash, offset, chunk_buf)?;
+            let len = core::cmp::min((update_len - offset) as usize, chunk_buf.len());
+            digest.update(&chunk_buf[..len]);
         }
+        output.copy_from_slice(digest.finalize().as_slice());
         Ok(())
     }
 
@@ -479,3 +486,32 @@ impl FirmwareUpdater {
         Ok(self.dfu)
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use futures::executor::block_on;
+    use sha1::{Digest, Sha1};
+
+    use super::*;
+    use crate::tests::MemFlash;
+
+    #[test]
+    fn can_verify() {
+        const STATE: Partition = Partition::new(0, 4096);
+        const DFU: Partition = Partition::new(65536, 131072);
+
+        let mut flash = MemFlash::<131072, 4096, 8>([0xFF; 131072]);
+
+        let update = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66];
+        let mut to_write = [0; 4096];
+        to_write[..7].copy_from_slice(update.as_slice());
+
+        let mut updater = FirmwareUpdater::new(DFU, STATE);
+        block_on(updater.write_firmware(0, to_write.as_slice(), &mut flash)).unwrap();
+        let mut chunk_buf = [0; 2];
+        let mut hash = [0; 20];
+        block_on(updater.hash::<_, Sha1>(&mut flash, update.len() as u32, &mut chunk_buf, &mut hash)).unwrap();
+
+        assert_eq!(Sha1::digest(update).as_slice(), hash);
+    }
+}
diff --git a/embassy-boot/boot/src/lib.rs b/embassy-boot/boot/src/lib.rs
index 6888a8055..da9055476 100644
--- a/embassy-boot/boot/src/lib.rs
+++ b/embassy-boot/boot/src/lib.rs
@@ -6,6 +6,7 @@
 mod fmt;
 
 mod boot_loader;
+mod digest_adapters;
 mod firmware_updater;
 mod partition;
 

From 8256ac104405400a15aa9a6a2d9afe38a552a98b Mon Sep 17 00:00:00 2001
From: Rasmus Melchior Jacobsen <rmja@laesoe.org>
Date: Tue, 4 Apr 2023 19:07:45 +0200
Subject: [PATCH 3/4] Use MemFlash::default() in sha1 verify test

---
 embassy-boot/boot/src/firmware_updater.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/embassy-boot/boot/src/firmware_updater.rs b/embassy-boot/boot/src/firmware_updater.rs
index 819e20201..fffb9a500 100644
--- a/embassy-boot/boot/src/firmware_updater.rs
+++ b/embassy-boot/boot/src/firmware_updater.rs
@@ -519,14 +519,14 @@ mod tests {
     use sha1::{Digest, Sha1};
 
     use super::*;
-    use crate::tests::MemFlash;
+    use crate::mem_flash::MemFlash;
 
     #[test]
-    fn can_verify() {
+    fn can_verify_sha1() {
         const STATE: Partition = Partition::new(0, 4096);
         const DFU: Partition = Partition::new(65536, 131072);
 
-        let mut flash = MemFlash::<131072, 4096, 8>([0xFF; 131072]);
+        let mut flash = MemFlash::<131072, 4096, 8>::default();
 
         let update = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66];
         let mut to_write = [0; 4096];

From d8e2f82569e1182e2a3a7ebe43af64f91d1e57e0 Mon Sep 17 00:00:00 2001
From: Rasmus Melchior Jacobsen <rmja@laesoe.org>
Date: Wed, 5 Apr 2023 06:57:56 +0200
Subject: [PATCH 4/4] Let update_len be usize for now

---
 embassy-boot/boot/src/firmware_updater.rs | 20 +++++++++-----------
 embassy-boot/boot/src/lib.rs              |  2 +-
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/embassy-boot/boot/src/firmware_updater.rs b/embassy-boot/boot/src/firmware_updater.rs
index fffb9a500..48e15024e 100644
--- a/embassy-boot/boot/src/firmware_updater.rs
+++ b/embassy-boot/boot/src/firmware_updater.rs
@@ -119,13 +119,11 @@ impl FirmwareUpdater {
         _state_and_dfu_flash: &mut F,
         _public_key: &[u8],
         _signature: &[u8],
-        _update_len: u32,
+        _update_len: usize,
         _aligned: &mut [u8],
     ) -> Result<(), FirmwareUpdaterError> {
-        let _read_size = _aligned.len();
-
         assert_eq!(_aligned.len(), F::WRITE_SIZE);
-        assert!(_update_len <= self.dfu.len() as u32);
+        assert!(_update_len <= self.dfu.len());
 
         #[cfg(feature = "ed25519-dalek")]
         {
@@ -182,10 +180,11 @@ impl FirmwareUpdater {
     pub async fn hash<F: AsyncNorFlash, D: Digest>(
         &mut self,
         dfu_flash: &mut F,
-        update_len: u32,
+        update_len: usize,
         chunk_buf: &mut [u8],
         output: &mut [u8],
     ) -> Result<(), FirmwareUpdaterError> {
+        let update_len = update_len as u32;
         let mut digest = D::new();
         for offset in (0..update_len).step_by(chunk_buf.len()) {
             self.dfu.read(dfu_flash, offset, chunk_buf).await?;
@@ -341,13 +340,11 @@ impl FirmwareUpdater {
         _state_and_dfu_flash: &mut F,
         _public_key: &[u8],
         _signature: &[u8],
-        _update_len: u32,
+        _update_len: usize,
         _aligned: &mut [u8],
     ) -> Result<(), FirmwareUpdaterError> {
-        let _read_size = _aligned.len();
-
         assert_eq!(_aligned.len(), F::WRITE_SIZE);
-        assert!(_update_len <= self.dfu.len() as u32);
+        assert!(_update_len <= self.dfu.len());
 
         #[cfg(feature = "ed25519-dalek")]
         {
@@ -402,10 +399,11 @@ impl FirmwareUpdater {
     pub fn hash_blocking<F: NorFlash, D: Digest>(
         &mut self,
         dfu_flash: &mut F,
-        update_len: u32,
+        update_len: usize,
         chunk_buf: &mut [u8],
         output: &mut [u8],
     ) -> Result<(), FirmwareUpdaterError> {
+        let update_len = update_len as u32;
         let mut digest = D::new();
         for offset in (0..update_len).step_by(chunk_buf.len()) {
             self.dfu.read_blocking(dfu_flash, offset, chunk_buf)?;
@@ -536,7 +534,7 @@ mod tests {
         block_on(updater.write_firmware(0, to_write.as_slice(), &mut flash)).unwrap();
         let mut chunk_buf = [0; 2];
         let mut hash = [0; 20];
-        block_on(updater.hash::<_, Sha1>(&mut flash, update.len() as u32, &mut chunk_buf, &mut hash)).unwrap();
+        block_on(updater.hash::<_, Sha1>(&mut flash, update.len(), &mut chunk_buf, &mut hash)).unwrap();
 
         assert_eq!(Sha1::digest(update).as_slice(), hash);
     }
diff --git a/embassy-boot/boot/src/lib.rs b/embassy-boot/boot/src/lib.rs
index 605e5253c..acd90996f 100644
--- a/embassy-boot/boot/src/lib.rs
+++ b/embassy-boot/boot/src/lib.rs
@@ -281,7 +281,7 @@ mod tests {
             &mut flash,
             &public_key.to_bytes(),
             &signature.to_bytes(),
-            firmware_len as u32,
+            firmware_len,
             &mut aligned,
         ))
         .is_ok());