diff options
| author | Gerhard de Clercq <[email protected]> | 2025-04-15 20:16:09 +0200 |
|---|---|---|
| committer | Gerhard de Clercq <[email protected]> | 2025-05-23 12:40:19 +0200 |
| commit | 68a45490fc1675f2171131ccbf01f690c4123f01 (patch) | |
| tree | 42606d9fa51bf50e6d7d84623123616600a70cce /embassy-usb-dfu/src | |
| parent | f7405493c184ce453ac3f7ba97f7f2689f978194 (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.rs | 33 |
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 | ||
| 24 | impl<'d, DFU: NorFlash, STATE: NorFlash, RST: Reset, const BLOCK_SIZE: usize> Control<'d, DFU, STATE, RST, BLOCK_SIZE> { | 27 | impl<'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, |
