mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 16:23:10 +00:00
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.
This commit is contained in:
parent
0909a6cd3f
commit
8aaffe82e7
@ -118,13 +118,13 @@ impl FirmwareUpdater {
|
|||||||
_state_and_dfu_flash: &mut F,
|
_state_and_dfu_flash: &mut F,
|
||||||
_public_key: &[u8],
|
_public_key: &[u8],
|
||||||
_signature: &[u8],
|
_signature: &[u8],
|
||||||
_update_len: usize,
|
_update_len: u32,
|
||||||
_aligned: &mut [u8],
|
_aligned: &mut [u8],
|
||||||
) -> Result<(), FirmwareUpdaterError> {
|
) -> Result<(), FirmwareUpdaterError> {
|
||||||
let _read_size = _aligned.len();
|
let _read_size = _aligned.len();
|
||||||
|
|
||||||
assert_eq!(_aligned.len(), F::WRITE_SIZE);
|
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")]
|
#[cfg(feature = "ed25519-dalek")]
|
||||||
{
|
{
|
||||||
@ -136,11 +136,8 @@ impl FirmwareUpdater {
|
|||||||
let signature = Signature::from_bytes(_signature).map_err(into_signature_error)?;
|
let signature = Signature::from_bytes(_signature).map_err(into_signature_error)?;
|
||||||
|
|
||||||
let mut digest = Sha512::new();
|
let mut digest = Sha512::new();
|
||||||
for offset in (0.._update_len).step_by(_aligned.len()) {
|
self.incremental_hash(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))
|
||||||
self.dfu.read(_state_and_dfu_flash, offset as u32, _aligned).await?;
|
.await?;
|
||||||
let len = core::cmp::min(_update_len - offset, _aligned.len());
|
|
||||||
digest.update(&_aligned[..len]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public_key
|
public_key
|
||||||
.verify(&digest.finalize(), &signature)
|
.verify(&digest.finalize(), &signature)
|
||||||
@ -161,11 +158,8 @@ impl FirmwareUpdater {
|
|||||||
let signature = Signature::try_from(&signature).map_err(into_signature_error)?;
|
let signature = Signature::try_from(&signature).map_err(into_signature_error)?;
|
||||||
|
|
||||||
let mut digest = Sha512::new();
|
let mut digest = Sha512::new();
|
||||||
for offset in (0.._update_len).step_by(_aligned.len()) {
|
self.incremental_hash(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))
|
||||||
self.dfu.read(_state_and_dfu_flash, offset as u32, _aligned).await?;
|
.await?;
|
||||||
let len = core::cmp::min(_update_len - offset, _aligned.len());
|
|
||||||
digest.update(&_aligned[..len]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let message = digest.finalize();
|
let message = digest.finalize();
|
||||||
let r = public_key.verify(&message, &signature);
|
let r = public_key.verify(&message, &signature);
|
||||||
@ -182,6 +176,22 @@ impl FirmwareUpdater {
|
|||||||
self.set_magic(_aligned, SWAP_MAGIC, _state_and_dfu_flash).await
|
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.
|
/// Mark to trigger firmware swap on next boot.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@ -317,14 +327,13 @@ impl FirmwareUpdater {
|
|||||||
_state_and_dfu_flash: &mut F,
|
_state_and_dfu_flash: &mut F,
|
||||||
_public_key: &[u8],
|
_public_key: &[u8],
|
||||||
_signature: &[u8],
|
_signature: &[u8],
|
||||||
_update_len: usize,
|
_update_len: u32,
|
||||||
_aligned: &mut [u8],
|
_aligned: &mut [u8],
|
||||||
) -> Result<(), FirmwareUpdaterError> {
|
) -> Result<(), FirmwareUpdaterError> {
|
||||||
let _end = self.dfu.from + _update_len;
|
|
||||||
let _read_size = _aligned.len();
|
let _read_size = _aligned.len();
|
||||||
|
|
||||||
assert_eq!(_aligned.len(), F::WRITE_SIZE);
|
assert_eq!(_aligned.len(), F::WRITE_SIZE);
|
||||||
assert!(_end <= self.dfu.to);
|
assert!(_update_len <= self.dfu.len() as u32);
|
||||||
|
|
||||||
#[cfg(feature = "ed25519-dalek")]
|
#[cfg(feature = "ed25519-dalek")]
|
||||||
{
|
{
|
||||||
@ -336,11 +345,7 @@ impl FirmwareUpdater {
|
|||||||
let signature = Signature::from_bytes(_signature).map_err(into_signature_error)?;
|
let signature = Signature::from_bytes(_signature).map_err(into_signature_error)?;
|
||||||
|
|
||||||
let mut digest = Sha512::new();
|
let mut digest = Sha512::new();
|
||||||
for offset in (0.._update_len).step_by(_aligned.len()) {
|
self.incremental_hash_blocking(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))?;
|
||||||
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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public_key
|
public_key
|
||||||
.verify(&digest.finalize(), &signature)
|
.verify(&digest.finalize(), &signature)
|
||||||
@ -361,11 +366,7 @@ impl FirmwareUpdater {
|
|||||||
let signature = Signature::try_from(&signature).map_err(into_signature_error)?;
|
let signature = Signature::try_from(&signature).map_err(into_signature_error)?;
|
||||||
|
|
||||||
let mut digest = Sha512::new();
|
let mut digest = Sha512::new();
|
||||||
for offset in (0.._update_len).step_by(_aligned.len()) {
|
self.incremental_hash_blocking(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))?;
|
||||||
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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let message = digest.finalize();
|
let message = digest.finalize();
|
||||||
let r = public_key.verify(&message, &signature);
|
let r = public_key.verify(&message, &signature);
|
||||||
@ -382,6 +383,22 @@ impl FirmwareUpdater {
|
|||||||
self.set_magic_blocking(_aligned, SWAP_MAGIC, _state_and_dfu_flash)
|
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.
|
/// Mark to trigger firmware swap on next boot.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
|
@ -308,7 +308,7 @@ mod tests {
|
|||||||
&mut flash,
|
&mut flash,
|
||||||
&public_key.to_bytes(),
|
&public_key.to_bytes(),
|
||||||
&signature.to_bytes(),
|
&signature.to_bytes(),
|
||||||
firmware_len,
|
firmware_len as u32,
|
||||||
&mut aligned,
|
&mut aligned,
|
||||||
))
|
))
|
||||||
.is_ok());
|
.is_ok());
|
||||||
|
Loading…
Reference in New Issue
Block a user