fix(nordic/ble): disconnect if the corresponding bond is erased
What changed, and why it matters
This change makes the Trezor Bluetooth layer disconnect an active Bluetooth connection before erasing a paired-device bond. Without the disconnect, the device could remain connected to a host whose pairing keys have just been deleted, which may allow the host to keep interacting with the wallet after the user thought access was revoked.
Treat as a security hardening fix with potential security relevance. Review whether upper-layer wallet protocols re-authenticate after bond deletion and confirm that connection_disconnect() is synchronous enough to prevent any further GATT/ATT operations before bt_unpair() completes. Consider adding a regression test that verifies the current connection is closed when bonds are erased.
Security signals we found
Missing disconnect before bond deletion
Stale authenticated BLE connection after credential revocation
Bluetooth pairing/bond state desynchronization
Evidence from the diff
In nordic/trezor/trezor-ble/src/ble/bonds.c, bonds_erase_all(), bonds_erase_current(), and bonds_erase_device() now call connection_disconnect() (or check the current connection’s address and disconnect if it matches) before bt_unpair(). Previously the code removed the bond while a connection using that bond could still be alive. The patch prevents a stale authenticated/encrypted connection from outliving its pairing material, which could lead to continued access or downgrade scenarios depending on how the upper layers handle a live link after bond deletion.
Changed components
nordic/trezor/trezor-ble/src/ble/bonds.cTrezor BLE bond managementTrezor Bluetooth connection handlingInspect captured patch +15 / −0
diff --git a/nordic/trezor/trezor-ble/src/ble/bonds.c b/nordic/trezor/trezor-ble/src/ble/bonds.c
index 27065df4c..c94068e04 100644
--- a/nordic/trezor/trezor-ble/src/ble/bonds.c
+++ b/nordic/trezor/trezor-ble/src/ble/bonds.c
@@ -35,6 +35,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "ble_internal.h"
bool bonds_erase_all(void) {
+ connection_disconnect();
int err = bt_unpair(BT_ID_DEFAULT, BT_ADDR_LE_ANY);
if (err) {
LOG_INF("Cannot delete bonds (err: %d)\n", err);
@@ -75,6 +76,8 @@ bool bonds_erase_current(void) {
return false;
}
+ connection_disconnect();
+
err = bt_unpair(BT_ID_DEFAULT, info.le.dst);
return err == 0;
@@ -85,12 +88,24 @@ bool bonds_erase_device(const bt_addr_le_t *addr) {
return false;
}
+ struct bt_conn *current = connection_get_current();
+
bool erased = false;
bt_addr_le_t target;
// Copy MAC and try both address types (ignore the input type)
memcpy(target.a.val, addr->a.val, BT_ADDR_SIZE);
+ if (current != NULL) {
+ struct bt_conn_info info;
+ int err = bt_conn_get_info(current, &info);
+ if (err == 0 &&
+ memcmp(info.le.dst->a.val, target.a.val, BT_ADDR_SIZE) == 0) {
+ // If the device is currently connected, disconnect it first
+ connection_disconnect();
+ }
+ }
+
target.type = BT_ADDR_LE_PUBLIC;
if (bt_unpair(BT_ID_DEFAULT, &target) == 0) {
erased = true;
Why this scored 42/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.