aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-01-30 19:40:00 -0800
committerJohan Hedberg <johan.hedberg@intel.com>2014-02-13 09:51:41 +0200
commit98a0b845c63cb74e90a72d1e864ea4be968bdd83 (patch)
tree464a1121e17e527de1abcc17a425e4e74b366079 /net
parentBluetooth: Remove unnecessary LTK type check from hci_add_ltk (diff)
downloadlinux-dev-98a0b845c63cb74e90a72d1e864ea4be968bdd83.tar.xz
linux-dev-98a0b845c63cb74e90a72d1e864ea4be968bdd83.zip
Bluetooth: Fix differentiating stored master vs slave LTK types
If LTK distribution happens in both directions we will have two LTKs for the same remote device: one which is used when we're connecting as master and another when we're connecting as slave. When looking up LTKs from the locally stored list we shouldn't blindly return the first match but also consider which type of key is in question. If we do not do this we may end up selecting an incorrect encryption key for a connection. This patch fixes the issue by always specifying to the LTK lookup functions whether we're looking for a master or a slave key. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_core.c22
-rw-r--r--net/bluetooth/hci_event.c2
-rw-r--r--net/bluetooth/smp.c3
3 files changed, 21 insertions, 6 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 {
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8c44bbe19add..7bb8094a3ff2 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3650,7 +3650,7 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
if (conn == NULL)
goto not_found;
- ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
+ ltk = hci_find_ltk(hdev, ev->ediv, ev->random, conn->out);
if (ltk == NULL)
goto not_found;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 9b1167007653..efe51ccdc615 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -699,7 +699,8 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
struct smp_ltk *key;
struct hci_conn *hcon = conn->hcon;
- key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type);
+ key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
+ hcon->out);
if (!key)
return 0;