aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-boot/boot/src/firmware_updater.rs67
-rw-r--r--embassy-boot/boot/src/lib.rs2
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 {
118 _state_and_dfu_flash: &mut F, 118 _state_and_dfu_flash: &mut F,
119 _public_key: &[u8], 119 _public_key: &[u8],
120 _signature: &[u8], 120 _signature: &[u8],
121 _update_len: usize, 121 _update_len: u32,
122 _aligned: &mut [u8], 122 _aligned: &mut [u8],
123 ) -> Result<(), FirmwareUpdaterError> { 123 ) -> Result<(), FirmwareUpdaterError> {
124 let _read_size = _aligned.len(); 124 let _read_size = _aligned.len();
125 125
126 assert_eq!(_aligned.len(), F::WRITE_SIZE); 126 assert_eq!(_aligned.len(), F::WRITE_SIZE);
127 assert!(_update_len <= self.dfu.len()); 127 assert!(_update_len <= self.dfu.len() as u32);
128 128
129 #[cfg(feature = "ed25519-dalek")] 129 #[cfg(feature = "ed25519-dalek")]
130 { 130 {
@@ -136,11 +136,8 @@ impl FirmwareUpdater {
136 let signature = Signature::from_bytes(_signature).map_err(into_signature_error)?; 136 let signature = Signature::from_bytes(_signature).map_err(into_signature_error)?;
137 137
138 let mut digest = Sha512::new(); 138 let mut digest = Sha512::new();
139 for offset in (0.._update_len).step_by(_aligned.len()) { 139 self.incremental_hash(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))
140 self.dfu.read(_state_and_dfu_flash, offset as u32, _aligned).await?; 140 .await?;
141 let len = core::cmp::min(_update_len - offset, _aligned.len());
142 digest.update(&_aligned[..len]);
143 }
144 141
145 public_key 142 public_key
146 .verify(&digest.finalize(), &signature) 143 .verify(&digest.finalize(), &signature)
@@ -161,11 +158,8 @@ impl FirmwareUpdater {
161 let signature = Signature::try_from(&signature).map_err(into_signature_error)?; 158 let signature = Signature::try_from(&signature).map_err(into_signature_error)?;
162 159
163 let mut digest = Sha512::new(); 160 let mut digest = Sha512::new();
164 for offset in (0.._update_len).step_by(_aligned.len()) { 161 self.incremental_hash(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))
165 self.dfu.read(_state_and_dfu_flash, offset as u32, _aligned).await?; 162 .await?;
166 let len = core::cmp::min(_update_len - offset, _aligned.len());
167 digest.update(&_aligned[..len]);
168 }
169 163
170 let message = digest.finalize(); 164 let message = digest.finalize();
171 let r = public_key.verify(&message, &signature); 165 let r = public_key.verify(&message, &signature);
@@ -182,6 +176,22 @@ impl FirmwareUpdater {
182 self.set_magic(_aligned, SWAP_MAGIC, _state_and_dfu_flash).await 176 self.set_magic(_aligned, SWAP_MAGIC, _state_and_dfu_flash).await
183 } 177 }
184 178
179 /// Iterate through the DFU and process all bytes with the provided closure.
180 pub async fn incremental_hash<F: AsyncNorFlash>(
181 &mut self,
182 dfu_flash: &mut F,
183 update_len: u32,
184 aligned: &mut [u8],
185 mut update: impl FnMut(&[u8]),
186 ) -> Result<(), FirmwareUpdaterError> {
187 for offset in (0..update_len).step_by(aligned.len()) {
188 self.dfu.read(dfu_flash, offset, aligned).await?;
189 let len = core::cmp::min((update_len - offset) as usize, aligned.len());
190 update(&aligned[..len]);
191 }
192 Ok(())
193 }
194
185 /// Mark to trigger firmware swap on next boot. 195 /// Mark to trigger firmware swap on next boot.
186 /// 196 ///
187 /// # Safety 197 /// # Safety
@@ -317,14 +327,13 @@ impl FirmwareUpdater {
317 _state_and_dfu_flash: &mut F, 327 _state_and_dfu_flash: &mut F,
318 _public_key: &[u8], 328 _public_key: &[u8],
319 _signature: &[u8], 329 _signature: &[u8],
320 _update_len: usize, 330 _update_len: u32,
321 _aligned: &mut [u8], 331 _aligned: &mut [u8],
322 ) -> Result<(), FirmwareUpdaterError> { 332 ) -> Result<(), FirmwareUpdaterError> {
323 let _end = self.dfu.from + _update_len;
324 let _read_size = _aligned.len(); 333 let _read_size = _aligned.len();
325 334
326 assert_eq!(_aligned.len(), F::WRITE_SIZE); 335 assert_eq!(_aligned.len(), F::WRITE_SIZE);
327 assert!(_end <= self.dfu.to); 336 assert!(_update_len <= self.dfu.len() as u32);
328 337
329 #[cfg(feature = "ed25519-dalek")] 338 #[cfg(feature = "ed25519-dalek")]
330 { 339 {
@@ -336,11 +345,7 @@ impl FirmwareUpdater {
336 let signature = Signature::from_bytes(_signature).map_err(into_signature_error)?; 345 let signature = Signature::from_bytes(_signature).map_err(into_signature_error)?;
337 346
338 let mut digest = Sha512::new(); 347 let mut digest = Sha512::new();
339 for offset in (0.._update_len).step_by(_aligned.len()) { 348 self.incremental_hash_blocking(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))?;
340 self.dfu.read_blocking(_state_and_dfu_flash, offset as u32, _aligned)?;
341 let len = core::cmp::min(_update_len - offset, _aligned.len());
342 digest.update(&_aligned[..len]);
343 }
344 349
345 public_key 350 public_key
346 .verify(&digest.finalize(), &signature) 351 .verify(&digest.finalize(), &signature)
@@ -361,11 +366,7 @@ impl FirmwareUpdater {
361 let signature = Signature::try_from(&signature).map_err(into_signature_error)?; 366 let signature = Signature::try_from(&signature).map_err(into_signature_error)?;
362 367
363 let mut digest = Sha512::new(); 368 let mut digest = Sha512::new();
364 for offset in (0.._update_len).step_by(_aligned.len()) { 369 self.incremental_hash_blocking(_state_and_dfu_flash, _update_len, _aligned, |x| digest.update(x))?;
365 self.dfu.read_blocking(_state_and_dfu_flash, offset as u32, _aligned)?;
366 let len = core::cmp::min(_update_len - offset, _aligned.len());
367 digest.update(&_aligned[..len]);
368 }
369 370
370 let message = digest.finalize(); 371 let message = digest.finalize();
371 let r = public_key.verify(&message, &signature); 372 let r = public_key.verify(&message, &signature);
@@ -382,6 +383,22 @@ impl FirmwareUpdater {
382 self.set_magic_blocking(_aligned, SWAP_MAGIC, _state_and_dfu_flash) 383 self.set_magic_blocking(_aligned, SWAP_MAGIC, _state_and_dfu_flash)
383 } 384 }
384 385
386 /// Iterate through the DFU and process all bytes with the provided closure.
387 pub fn incremental_hash_blocking<F: NorFlash>(
388 &mut self,
389 dfu_flash: &mut F,
390 update_len: u32,
391 aligned: &mut [u8],
392 mut update: impl FnMut(&[u8]),
393 ) -> Result<(), FirmwareUpdaterError> {
394 for offset in (0..update_len).step_by(aligned.len()) {
395 self.dfu.read_blocking(dfu_flash, offset, aligned)?;
396 let len = core::cmp::min((update_len - offset) as usize, aligned.len());
397 update(&aligned[..len]);
398 }
399 Ok(())
400 }
401
385 /// Mark to trigger firmware swap on next boot. 402 /// Mark to trigger firmware swap on next boot.
386 /// 403 ///
387 /// # Safety 404 /// # 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 {
308 &mut flash, 308 &mut flash,
309 &public_key.to_bytes(), 309 &public_key.to_bytes(),
310 &signature.to_bytes(), 310 &signature.to_bytes(),
311 firmware_len, 311 firmware_len as u32,
312 &mut aligned, 312 &mut aligned,
313 )) 313 ))
314 .is_ok()); 314 .is_ok());