Skip to content

Commit

Permalink
Save link_key in CTKD over BR/EDR
Browse files Browse the repository at this point in the history
Since keystore.update() overwrites all existing keys, the existing link
key will be wiped out. To avoid this, SMP also need to keep the key.
  • Loading branch information
zxzxwu committed Jan 17, 2024
1 parent 46ceea7 commit acd9d99
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 3 deletions.
8 changes: 5 additions & 3 deletions bumble/smp.py
Original file line number Diff line number Diff line change
Expand Up @@ -1134,16 +1134,18 @@ def derive_link_key(cls, ltk: bytes, ct2: bool) -> bytes:

async def get_link_key_and_derive_ltk(self) -> None:
'''Retrieves BR/EDR Link Key from storage and derive it to LE LTK.'''
link_key = await self.manager.device.get_link_key(self.connection.peer_address)
if link_key is None:
self.link_key = await self.manager.device.get_link_key(
self.connection.peer_address
)
if self.link_key is None:
logging.warning(
'Try to derive LTK but host does not have the LK. Send a SMP_PAIRING_FAILED but the procedure will not be paused!'
)
self.send_pairing_failed(
SMP_CROSS_TRANSPORT_KEY_DERIVATION_NOT_ALLOWED_ERROR
)
else:
self.ltk = self.derive_ltk(link_key, self.ct2)
self.ltk = self.derive_ltk(self.link_key, self.ct2)

def distribute_keys(self) -> None:
# Distribute the keys as required
Expand Down
7 changes: 7 additions & 0 deletions tests/self_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,13 @@ async def test_self_smp_over_classic():
MockSmpSession.send_public_key_command.assert_not_called()
MockSmpSession.send_pairing_random_command.assert_not_called()

for i in range(2):
assert (
await two_devices.devices[i].keystore.get(
str(two_devices.connections[i].peer_address)
)
).link_key


# -----------------------------------------------------------------------------
@pytest.mark.asyncio
Expand Down

0 comments on commit acd9d99

Please sign in to comment.