aboutsummaryrefslogtreecommitdiff
path: root/embassy-usb-dfu/src
diff options
context:
space:
mode:
authorGerhard de Clercq <[email protected]>2025-04-15 20:16:09 +0200
committerGerhard de Clercq <[email protected]>2025-05-23 12:40:19 +0200
commit68a45490fc1675f2171131ccbf01f690c4123f01 (patch)
tree42606d9fa51bf50e6d7d84623123616600a70cce /embassy-usb-dfu/src
parentf7405493c184ce453ac3f7ba97f7f2689f978194 (diff)
[embassy-usb-dfu] support ed25519 verification
This commit adds the ability to verify that USB DFU updates are correctly signed using ed25519. This required adding support to embassy-boot for reading from the DFU partition.
Diffstat (limited to 'embassy-usb-dfu/src')
-rw-r--r--embassy-usb-dfu/src/dfu.rs33
1 files changed, 30 insertions, 3 deletions
diff --git a/embassy-usb-dfu/src/dfu.rs b/embassy-usb-dfu/src/dfu.rs
index 0f39d906b..9a2f125fb 100644
--- a/embassy-usb-dfu/src/dfu.rs
+++ b/embassy-usb-dfu/src/dfu.rs
@@ -19,11 +19,19 @@ pub struct Control<'d, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_S
19 offset: usize, 19 offset: usize,
20 buf: AlignedBuffer<BLOCK_SIZE>, 20 buf: AlignedBuffer<BLOCK_SIZE>,
21 reset: RST, 21 reset: RST,
22
23 #[cfg(feature = "_verify")]
24 public_key: &'static [u8; 32],
22} 25}
23 26
24impl<'d, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize> Control<'d, DFU, STATE, RST, BLOCK_SIZE> { 27impl<'d, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize> Control<'d, DFU, STATE, RST, BLOCK_SIZE> {
25 /// Create a new DFU instance to handle DFU transfers. 28 /// Create a new DFU instance to handle DFU transfers.
26 pub fn new(updater: BlockingFirmwareUpdater<'d, DFU, STATE>, attrs: DfuAttributes, reset: RST) -> Self { 29 pub fn new(
30 updater: BlockingFirmwareUpdater<'d, DFU, STATE>,
31 attrs: DfuAttributes,
32 reset: RST,
33 #[cfg(feature = "_verify")] public_key: &'static [u8; 32],
34 ) -> Self {
27 Self { 35 Self {
28 updater, 36 updater,
29 attrs, 37 attrs,
@@ -32,6 +40,9 @@ impl<'d, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize> Co
32 offset: 0, 40 offset: 0,
33 buf: AlignedBuffer([0; BLOCK_SIZE]), 41 buf: AlignedBuffer([0; BLOCK_SIZE]),
34 reset, 42 reset,
43
44 #[cfg(feature = "_verify")]
45 public_key,
35 } 46 }
36 } 47 }
37 48
@@ -102,7 +113,23 @@ impl<'d, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize> Ha
102 if final_transfer { 113 if final_transfer {
103 debug!("Receiving final transfer"); 114 debug!("Receiving final transfer");
104 115
105 match self.updater.mark_updated() { 116 #[cfg(feature = "_verify")]
117 let update_res: Result<(), FirmwareUpdaterError> = {
118 const SIGNATURE_LEN: usize = 64;
119
120 let mut signature = [0; SIGNATURE_LEN];
121 let update_len = (self.offset - SIGNATURE_LEN) as u32;
122
123 self.updater.read_dfu(update_len, &mut signature).and_then(|_| {
124 self.updater
125 .verify_and_mark_updated(self.public_key, &signature, update_len)
126 })
127 };
128
129 #[cfg(not(feature = "_verify"))]
130 let update_res = self.updater.mark_updated();
131
132 match update_res {
106 Ok(_) => { 133 Ok(_) => {
107 self.status = Status::Ok; 134 self.status = Status::Ok;
108 self.state = State::ManifestSync; 135 self.state = State::ManifestSync;
@@ -168,7 +195,7 @@ impl<'d, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize> Ha
168 Some(InResponse::Accepted(&buf[0..1])) 195 Some(InResponse::Accepted(&buf[0..1]))
169 } 196 }
170 Ok(Request::Upload) if self.attrs.contains(DfuAttributes::CAN_UPLOAD) => { 197 Ok(Request::Upload) if self.attrs.contains(DfuAttributes::CAN_UPLOAD) => {
171 //TODO: FirmwareUpdater does not provide a way of reading the active partition, can't upload. 198 //TODO: FirmwareUpdater provides a way of reading the active partition so we could in theory add functionality to upload firmware.
172 Some(InResponse::Rejected) 199 Some(InResponse::Rejected)
173 } 200 }
174 _ => None, 201 _ => None,