From 6c6bd8c49ebd70c12482634c5ce98b4231468d82 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Fri, 20 Mar 2020 19:42:53 +0100 Subject: [PATCH] Bluetooth: host: Fix directed advertising from privacy-disabled peer Fix directed advertising from privacy disabled peer. In this case we need to have the local IRK in the controllers resolving list in order to have the controller resolve the initiator address of the directed advertising pdu (ADV_DIR_IND). Signed-off-by: Joakim Andersson --- subsys/bluetooth/host/hci_core.c | 19 +++++++++++++++---- subsys/bluetooth/host/keys.c | 9 +++++++-- subsys/bluetooth/host/smp.c | 10 ++++++++++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index aa8b6b71510..7ca50e3da4b 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -1339,7 +1339,12 @@ static void enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) #if defined(CONFIG_BT_SMP) if (atomic_test_and_clear_bit(bt_dev.flags, BT_DEV_ID_PENDING)) { - bt_keys_foreach(BT_KEYS_IRK, update_pending_id, NULL); + if (IS_ENABLED(CONFIG_BT_CENTRAL) && + IS_ENABLED(CONFIG_BT_PRIVACY)) { + bt_keys_foreach(BT_KEYS_ALL, update_pending_id, NULL); + } else { + bt_keys_foreach(BT_KEYS_IRK, update_pending_id, NULL); + } } #endif @@ -3178,7 +3183,9 @@ done: static void keys_add_id(struct bt_keys *keys, void *data) { - hci_id_add(keys->id, &keys->addr, keys->irk.val); + if (keys != (struct bt_keys *)data) { + hci_id_add(keys->id, &keys->addr, keys->irk.val); + } } void bt_id_del(struct bt_keys *keys) @@ -3229,8 +3236,12 @@ void bt_id_del(struct bt_keys *keys) /* We checked size + 1 earlier, so here we know we can fit again */ if (bt_dev.le.rl_entries > bt_dev.le.rl_size) { bt_dev.le.rl_entries--; - keys->keys &= ~BT_KEYS_IRK; - bt_keys_foreach(BT_KEYS_IRK, keys_add_id, NULL); + if (IS_ENABLED(CONFIG_BT_CENTRAL) && + IS_ENABLED(CONFIG_BT_PRIVACY)) { + bt_keys_foreach(BT_KEYS_ALL, keys_add_id, keys); + } else { + bt_keys_foreach(BT_KEYS_IRK, keys_add_id, keys); + } goto done; } diff --git a/subsys/bluetooth/host/keys.c b/subsys/bluetooth/host/keys.c index d3e4c9ce342..288e5e8823b 100644 --- a/subsys/bluetooth/host/keys.c +++ b/subsys/bluetooth/host/keys.c @@ -236,7 +236,8 @@ void bt_keys_clear(struct bt_keys *keys) { BT_DBG("%s (keys 0x%04x)", bt_addr_le_str(&keys->addr), keys->keys); - if (keys->keys & BT_KEYS_IRK) { + if ((IS_ENABLED(CONFIG_BT_CENTRAL) && IS_ENABLED(CONFIG_BT_PRIVACY)) || + keys->keys & BT_KEYS_IRK) { bt_id_del(keys); } @@ -393,7 +394,11 @@ static int keys_commit(void) * called multiple times for the same address, especially if * the keys were already removed. */ - bt_keys_foreach(BT_KEYS_IRK, id_add, NULL); + if (IS_ENABLED(CONFIG_BT_CENTRAL) && IS_ENABLED(CONFIG_BT_PRIVACY)) { + bt_keys_foreach(BT_KEYS_ALL, id_add, NULL); + } else { + bt_keys_foreach(BT_KEYS_IRK, id_add, NULL); + } return 0; } diff --git a/subsys/bluetooth/host/smp.c b/subsys/bluetooth/host/smp.c index 1c8faafe766..3ddec039f90 100644 --- a/subsys/bluetooth/host/smp.c +++ b/subsys/bluetooth/host/smp.c @@ -4405,6 +4405,16 @@ static void bt_smp_encrypt_change(struct bt_l2cap_chan *chan, atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_SIGNING_INFO); } + if (IS_ENABLED(CONFIG_BT_CENTRAL) && + IS_ENABLED(CONFIG_BT_PRIVACY) && + !(smp->remote_dist & BT_SMP_DIST_ID_KEY)) { + /* To resolve directed advertising we need our local IRK + * in the controllers resolving list, add it now since the + * peer has no identity key. + */ + bt_id_add(conn->le.keys); + } + atomic_set_bit(smp->flags, SMP_FLAG_KEYS_DISTR); /* Slave distributes it's keys first */