fix(core/bootloader): send response before deleting bonds in factory reset
What changed, and why it matters
This bootloader patch changes the order of operations during a factory reset (wipe). Previously, the device tried to delete Bluetooth pairing information ('bonds') before telling the host computer that the wipe succeeded. Deleting bonds can disconnect the device, so the success message might never reach the host, leaving the user or software unsure whether the wipe completed. The fix sends the success message first, then waits briefly, then deletes the bonds. This is primarily a reliability/UX fix; it does not appear to be a security vulnerability in the sense of theft or unauthorized access.
Treat as a normal reliability fix. No urgent security response is indicated. If a security advisory is issued, it should frame the issue as a factory-reset confirmation reliability problem rather than a confidentiality or integrity vulnerability. Review whether the 100 ms delay is sufficient across all host OSes and consider idempotent handling of duplicate wipe commands.
Security signals we found
Order-of-operations change around destructive operation and host notification
Communication response may be lost due to interface teardown during factory reset
No authentication, cryptographic, or memory-safety changes present
Evidence from the diff
In core/embed/projects/bootloader/workflow/wf_wipe_device.c, the success response is now sent before wipe_bonds(iface) is called. A 100 ms delay is added after sending success. The error path for erase_device failure is split: an error message is sent immediately after the failed erase, but the function still returns WF_ERROR after the subsequent cleanup/bond-deletion path. The change prevents the BLE bond deletion from tearing down the USB/communication interface before the host receives the final protocol response.
Changed components
Trezor Core bootloader factory reset workflowcore/embed/projects/bootloader/workflow/wf_wipe_device.cBLE bond deletion path (USE_BLE)Host protocol response pathInspect captured patch +11 / −4
diff --git a/core/embed/projects/bootloader/workflow/wf_wipe_device.c b/core/embed/projects/bootloader/workflow/wf_wipe_device.c
index 08962e6f..143cbec8 100644
--- a/core/embed/projects/bootloader/workflow/wf_wipe_device.c
+++ b/core/embed/projects/bootloader/workflow/wf_wipe_device.c
@@ -97,12 +97,23 @@ workflow_result_t workflow_wipe_device(protob_io_t* iface) {
ui_screen_wipe();
secbool wipe_result = erase_device(ui_screen_wipe_progress);
+ if (sectrue != wipe_result) {
+ send_error_conditionally(iface, "Could not erase flash");
+ }
+
#ifdef USE_BACKUP_RAM
if (!backup_ram_erase_protected()) {
return WF_ERROR;
}
#endif
+ // sending success earlier to notify host before bonds deletion causes
+ // disconnect
+ if (iface != NULL) {
+ send_msg_success(iface, NULL);
+ systick_delay_ms(100);
+ }
+
#ifdef USE_BLE
if (!wipe_bonds(iface)) {
return WF_ERROR;
@@ -110,14 +121,10 @@ workflow_result_t workflow_wipe_device(protob_io_t* iface) {
#endif
if (sectrue != wipe_result) {
- send_error_conditionally(iface, "Could not erase flash");
screen_wipe_fail();
return WF_ERROR;
}
- if (iface != NULL) {
- send_msg_success(iface, NULL);
- }
screen_wipe_success();
return WF_OK_DEVICE_WIPED;
}
Why this scored 33/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.