[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.
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
MEMORY
|
||||
{
|
||||
/* NOTE 1 K = 1 KiBi = 1024 bytes */
|
||||
BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K
|
||||
BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K
|
||||
FLASH : ORIGIN = 0x08008000, LENGTH = 128K
|
||||
DFU : ORIGIN = 0x08028000, LENGTH = 132K
|
||||
BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 48K
|
||||
BOOTLOADER_STATE : ORIGIN = 0x0800C000, LENGTH = 4K
|
||||
FLASH : ORIGIN = 0x0800D000, LENGTH = 120K
|
||||
DFU : ORIGIN = 0x0802B000, LENGTH = 120K
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K
|
||||
}
|
||||
|
||||
|
||||
2
examples/boot/application/stm32wb-dfu/secrets/key.sec
Normal file
2
examples/boot/application/stm32wb-dfu/secrets/key.sec
Normal file
@@ -0,0 +1,2 @@
|
||||
untrusted comment: signify secret key
|
||||
RWRCSwAAAAATdHQF3B4jEIoNZrjADRp2LbjJjNdNNzKwTCe4IB6mDNq96pe53nbNxwbdCc/T4hrz7W+Kx1MwrZ0Yz5xebSK5Z0Kh/3Cdf039U5f+eoTDS2fIGbohyUbrtwKzjyE0qXI=
|
||||
@@ -30,6 +30,7 @@ defmt = [
|
||||
"embassy-usb/defmt",
|
||||
"embassy-usb-dfu/defmt"
|
||||
]
|
||||
verify = ["embassy-usb-dfu/ed25519-salty"]
|
||||
|
||||
[profile.dev]
|
||||
debug = 2
|
||||
|
||||
@@ -28,6 +28,32 @@ cargo objcopy --release -- -O binary fw.bin
|
||||
dfu-util -d c0de:cafe -w -D fw.bin
|
||||
```
|
||||
|
||||
### 3. Sign Updates Before Flashing (Optional)
|
||||
|
||||
Currently, embassy-usb-dfu only supports a limited implementation of the generic support for ed25519-based update verfication in embassy-boot. This implementation assumes that a signature is simply concatenated to the end of an update binary. For more details, please see https://embassy.dev/book/#_verification and/or refer to the documentation for embassy-boot-dfu.
|
||||
|
||||
To sign (and then verify) application updates, you will first need to generate a key pair:
|
||||
|
||||
```
|
||||
signify-openbsd -G -n -p secrets/key.pub -s secrets/key.sec
|
||||
tail -n1 secrets/key.pub | base64 -d -i - | dd ibs=10 skip=1 > secrets/key.pub.short
|
||||
```
|
||||
|
||||
Then you will need to sign all you binaries with the private key:
|
||||
|
||||
```
|
||||
cargo objcopy --release -- -O binary fw.bin
|
||||
shasum -a 512 -b fw.bin | head -c128 | xxd -p -r > target/fw-hash.txt
|
||||
signify-openbsd -S -s secrets/key.sec -m target/fw-hash.txt -x target/fw-hash.sig
|
||||
cp fw.bin fw-signed.bin
|
||||
tail -n1 target/fw-hash.sig | base64 -d -i - | dd ibs=10 skip=1 >> fw-signed.bin
|
||||
dfu-util -d c0de:cafe -w -D fw-signed.bin
|
||||
```
|
||||
|
||||
Finally, as shown in this example with the `verify` feature flag enabled, you then need to embed the public key into your bootloader so that it can verify update signatures.
|
||||
|
||||
N.B. Please note that the exact steps above are NOT a good example of how to manage your keys securely. In a production environment, you should take great care to ensure that (at least the private key) is protected and not leaked into your version control system.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- Make sure your device is in DFU mode before flashing
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
MEMORY
|
||||
{
|
||||
/* NOTE 1 K = 1 KiBi = 1024 bytes */
|
||||
FLASH : ORIGIN = 0x08000000, LENGTH = 24K
|
||||
BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K
|
||||
ACTIVE : ORIGIN = 0x08008000, LENGTH = 128K
|
||||
DFU : ORIGIN = 0x08028000, LENGTH = 132K
|
||||
FLASH : ORIGIN = 0x08000000, LENGTH = 48K
|
||||
BOOTLOADER_STATE : ORIGIN = 0x0800C000, LENGTH = 4K
|
||||
ACTIVE : ORIGIN = 0x0800D000, LENGTH = 120K
|
||||
DFU : ORIGIN = 0x0802B000, LENGTH = 120K
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
gB<EFBFBD><EFBFBD>p<EFBFBD>M<EFBFBD>S<EFBFBD><EFBFBD>z<EFBFBD><EFBFBD>Kg<EFBFBD><19>!<21>F<EFBFBD><46><02><>!4<>r
|
||||
@@ -25,6 +25,12 @@ bind_interrupts!(struct Irqs {
|
||||
// N.B. update to a custom GUID for your own device!
|
||||
const DEVICE_INTERFACE_GUIDS: &[&str] = &["{EAA9A5DC-30BA-44BC-9232-606CDC875321}"];
|
||||
|
||||
// This is a randomly generated example key.
|
||||
//
|
||||
// N.B. Please replace with your own!
|
||||
#[cfg(feature = "verify")]
|
||||
static PUBLIC_SIGNING_KEY: &[u8; 32] = include_bytes!("../secrets/key.pub.short");
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let mut config = embassy_stm32::Config::default();
|
||||
@@ -57,7 +63,13 @@ fn main() -> ! {
|
||||
let mut config_descriptor = [0; 256];
|
||||
let mut bos_descriptor = [0; 256];
|
||||
let mut control_buf = [0; 4096];
|
||||
|
||||
#[cfg(not(feature = "verify"))]
|
||||
let mut state = Control::new(updater, DfuAttributes::CAN_DOWNLOAD, ResetImmediate);
|
||||
|
||||
#[cfg(feature = "verify")]
|
||||
let mut state = Control::new(updater, DfuAttributes::CAN_DOWNLOAD, ResetImmediate, PUBLIC_SIGNING_KEY);
|
||||
|
||||
let mut builder = Builder::new(
|
||||
driver,
|
||||
config,
|
||||
|
||||
Reference in New Issue
Block a user