diff options
Diffstat (limited to 'net/bluetooth/hci_core.c')
-rw-r--r-- | net/bluetooth/hci_core.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 180473d965f6..d370b432aea6 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2605,7 +2605,16 @@ static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, return false; } -struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) +static bool ltk_type_master(u8 type) +{ + if (type == HCI_SMP_STK || type == HCI_SMP_LTK) + return true; + + return false; +} + +struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8], + bool master) { struct smp_ltk *k; @@ -2614,6 +2623,9 @@ struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) memcmp(rand, k->rand, sizeof(k->rand))) continue; + if (ltk_type_master(k->type) != master) + continue; + return k; } @@ -2621,13 +2633,14 @@ struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) } struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 addr_type) + u8 addr_type, bool master) { struct smp_ltk *k; list_for_each_entry(k, &hdev->long_term_keys, list) if (addr_type == k->bdaddr_type && - bacmp(bdaddr, &k->bdaddr) == 0) + bacmp(bdaddr, &k->bdaddr) == 0 && + ltk_type_master(k->type) == master) return k; return NULL; @@ -2691,8 +2704,9 @@ int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, ediv, u8 rand[8]) { struct smp_ltk *key, *old_key; + bool master = ltk_type_master(type); - old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type); + old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master); if (old_key) key = old_key; else { |