aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinicius Costa Gomes <vinicius.gomes@openbossa.org>2012-02-02 19:08:00 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2012-02-13 10:01:32 -0500
commitb899efaf9b26cadb084752862490b4fc44bc3169 (patch)
treef0fc1dae801b98ae8b525798a48c292cfaf15329
parent650f726d16a3f25153d785b531516f6e90d2014f (diff)
Bluetooth: Add new structures for handling SMP Long Term Keys
This includes a new list for storing the keys and a new structure used to represent each key. Some notes: authenticated is used to identify that the key may be used to setup a HIGH security link. As the same list is used to store both the STK's and the LTK's the type field is used so we can separate between those two types of keys and if the key should be used when in the master or slave role. Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
-rw-r--r--include/net/bluetooth/hci.h5
-rw-r--r--include/net/bluetooth/hci_core.h16
-rw-r--r--net/bluetooth/hci_core.c31
3 files changed, 52 insertions, 0 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index cb9097acbf4..83f045a515a 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -274,6 +274,11 @@ enum {
274#define HCI_LK_SMP_LTK 0x81 274#define HCI_LK_SMP_LTK 0x81
275#define HCI_LK_SMP_IRK 0x82 275#define HCI_LK_SMP_IRK 0x82
276#define HCI_LK_SMP_CSRK 0x83 276#define HCI_LK_SMP_CSRK 0x83
277/* The spec doesn't define types for SMP keys, the _MASTER suffix is implied */
278#define HCI_SMP_STK 0x80
279#define HCI_SMP_STK_SLAVE 0x81
280#define HCI_SMP_LTK 0x82
281#define HCI_SMP_LTK_SLAVE 0x83
277 282
278/* ---- HCI Error Codes ---- */ 283/* ---- HCI Error Codes ---- */
279#define HCI_ERROR_AUTH_FAILURE 0x05 284#define HCI_ERROR_AUTH_FAILURE 0x05
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 896d9e4955f..c998176a503 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -88,6 +88,18 @@ struct bt_uuid {
88 u8 svc_hint; 88 u8 svc_hint;
89}; 89};
90 90
91struct smp_ltk {
92 struct list_head list;
93 bdaddr_t bdaddr;
94 u8 bdaddr_type;
95 u8 authenticated;
96 u8 type;
97 u8 enc_size;
98 __le16 ediv;
99 u8 rand[8];
100 u8 val[16];
101} __packed;
102
91struct key_master_id { 103struct key_master_id {
92 __le16 ediv; 104 __le16 ediv;
93 u8 rand[8]; 105 u8 rand[8];
@@ -239,6 +251,8 @@ struct hci_dev {
239 251
240 struct list_head link_keys; 252 struct list_head link_keys;
241 253
254 struct list_head long_term_keys;
255
242 struct list_head remote_oob_data; 256 struct list_head remote_oob_data;
243 257
244 struct list_head adv_entries; 258 struct list_head adv_entries;
@@ -647,8 +661,10 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
647struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]); 661struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
648struct link_key *hci_find_link_key_type(struct hci_dev *hdev, 662struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
649 bdaddr_t *bdaddr, u8 type); 663 bdaddr_t *bdaddr, u8 type);
664int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr);
650int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, 665int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
651 u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]); 666 u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
667int hci_smp_ltks_clear(struct hci_dev *hdev);
652int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); 668int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
653 669
654int hci_remote_oob_data_clear(struct hci_dev *hdev); 670int hci_remote_oob_data_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 45e2d2a72b1..a28e637152f 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1163,6 +1163,18 @@ int hci_link_keys_clear(struct hci_dev *hdev)
1163 return 0; 1163 return 0;
1164} 1164}
1165 1165
1166int hci_smp_ltks_clear(struct hci_dev *hdev)
1167{
1168 struct smp_ltk *k, *tmp;
1169
1170 list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1171 list_del(&k->list);
1172 kfree(k);
1173 }
1174
1175 return 0;
1176}
1177
1166struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) 1178struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
1167{ 1179{
1168 struct link_key *k; 1180 struct link_key *k;
@@ -1355,6 +1367,23 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
1355 return 0; 1367 return 0;
1356} 1368}
1357 1369
1370int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1371{
1372 struct smp_ltk *k, *tmp;
1373
1374 list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1375 if (bacmp(bdaddr, &k->bdaddr))
1376 continue;
1377
1378 BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
1379
1380 list_del(&k->list);
1381 kfree(k);
1382 }
1383
1384 return 0;
1385}
1386
1358/* HCI command timer function */ 1387/* HCI command timer function */
1359static void hci_cmd_timer(unsigned long arg) 1388static void hci_cmd_timer(unsigned long arg)
1360{ 1389{
@@ -1638,6 +1667,7 @@ int hci_register_dev(struct hci_dev *hdev)
1638 INIT_LIST_HEAD(&hdev->uuids); 1667 INIT_LIST_HEAD(&hdev->uuids);
1639 1668
1640 INIT_LIST_HEAD(&hdev->link_keys); 1669 INIT_LIST_HEAD(&hdev->link_keys);
1670 INIT_LIST_HEAD(&hdev->long_term_keys);
1641 1671
1642 INIT_LIST_HEAD(&hdev->remote_oob_data); 1672 INIT_LIST_HEAD(&hdev->remote_oob_data);
1643 1673
@@ -1739,6 +1769,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
1739 hci_blacklist_clear(hdev); 1769 hci_blacklist_clear(hdev);
1740 hci_uuids_clear(hdev); 1770 hci_uuids_clear(hdev);
1741 hci_link_keys_clear(hdev); 1771 hci_link_keys_clear(hdev);
1772 hci_smp_ltks_clear(hdev);
1742 hci_remote_oob_data_clear(hdev); 1773 hci_remote_oob_data_clear(hdev);
1743 hci_adv_entries_clear(hdev); 1774 hci_adv_entries_clear(hdev);
1744 hci_dev_unlock(hdev); 1775 hci_dev_unlock(hdev);