aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-01-30 22:40:00 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2014-02-13 02:51:41 -0500
commit98a0b845c63cb74e90a72d1e864ea4be968bdd83 (patch)
tree464a1121e17e527de1abcc17a425e4e74b366079
parenta513e260ce25eaa5e8c6b834a70085be1d6f40c0 (diff)
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>
-rw-r--r--include/net/bluetooth/hci_core.h5
-rw-r--r--net/bluetooth/hci_core.c22
-rw-r--r--net/bluetooth/hci_event.c2
-rw-r--r--net/bluetooth/smp.c3
4 files changed, 24 insertions, 8 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 8d225e4ea2ce..378e2f32cfa0 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -757,12 +757,13 @@ int hci_link_keys_clear(struct hci_dev *hdev);
757struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); 757struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
758int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, 758int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
759 bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len); 759 bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
760struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]); 760struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8],
761 bool master);
761int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, 762int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
762 int new_key, u8 authenticated, u8 tk[16], u8 enc_size, 763 int new_key, u8 authenticated, u8 tk[16], u8 enc_size,
763 __le16 ediv, u8 rand[8]); 764 __le16 ediv, u8 rand[8]);
764struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 765struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
765 u8 addr_type); 766 u8 addr_type, bool master);
766int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr); 767int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr);
767int hci_smp_ltks_clear(struct hci_dev *hdev); 768int hci_smp_ltks_clear(struct hci_dev *hdev);
768int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); 769int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
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,
2605 return false; 2605 return false;
2606} 2606}
2607 2607
2608struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) 2608static bool ltk_type_master(u8 type)
2609{
2610 if (type == HCI_SMP_STK || type == HCI_SMP_LTK)
2611 return true;
2612
2613 return false;
2614}
2615
2616struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8],
2617 bool master)
2609{ 2618{
2610 struct smp_ltk *k; 2619 struct smp_ltk *k;
2611 2620
@@ -2614,6 +2623,9 @@ struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
2614 memcmp(rand, k->rand, sizeof(k->rand))) 2623 memcmp(rand, k->rand, sizeof(k->rand)))
2615 continue; 2624 continue;
2616 2625
2626 if (ltk_type_master(k->type) != master)
2627 continue;
2628
2617 return k; 2629 return k;
2618 } 2630 }
2619 2631
@@ -2621,13 +2633,14 @@ struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
2621} 2633}
2622 2634
2623struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 2635struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
2624 u8 addr_type) 2636 u8 addr_type, bool master)
2625{ 2637{
2626 struct smp_ltk *k; 2638 struct smp_ltk *k;
2627 2639
2628 list_for_each_entry(k, &hdev->long_term_keys, list) 2640 list_for_each_entry(k, &hdev->long_term_keys, list)
2629 if (addr_type == k->bdaddr_type && 2641 if (addr_type == k->bdaddr_type &&
2630 bacmp(bdaddr, &k->bdaddr) == 0) 2642 bacmp(bdaddr, &k->bdaddr) == 0 &&
2643 ltk_type_master(k->type) == master)
2631 return k; 2644 return k;
2632 2645
2633 return NULL; 2646 return NULL;
@@ -2691,8 +2704,9 @@ int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
2691 ediv, u8 rand[8]) 2704 ediv, u8 rand[8])
2692{ 2705{
2693 struct smp_ltk *key, *old_key; 2706 struct smp_ltk *key, *old_key;
2707 bool master = ltk_type_master(type);
2694 2708
2695 old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type); 2709 old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master);
2696 if (old_key) 2710 if (old_key)
2697 key = old_key; 2711 key = old_key;
2698 else { 2712 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)
3650 if (conn == NULL) 3650 if (conn == NULL)
3651 goto not_found; 3651 goto not_found;
3652 3652
3653 ltk = hci_find_ltk(hdev, ev->ediv, ev->random); 3653 ltk = hci_find_ltk(hdev, ev->ediv, ev->random, conn->out);
3654 if (ltk == NULL) 3654 if (ltk == NULL)
3655 goto not_found; 3655 goto not_found;
3656 3656
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)
699 struct smp_ltk *key; 699 struct smp_ltk *key;
700 struct hci_conn *hcon = conn->hcon; 700 struct hci_conn *hcon = conn->hcon;
701 701
702 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type); 702 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
703 hcon->out);
703 if (!key) 704 if (!key)
704 return 0; 705 return 0;
705 706