* [PATCH 0/8] New MGMT messages for SMP Long Term Keys
@ 2012-01-13 19:39 Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 1/8] Bluetooth: Add structures for the new LTK exchange messages Vinicius Costa Gomes
` (7 more replies)
0 siblings, 8 replies; 20+ messages in thread
From: Vinicius Costa Gomes @ 2012-01-13 19:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
Hi,
This is the last version of the code that will allow the permanent
storage of SMP Long Term Keys.
The main changes from the last version are:
* In the structure that represents a LTK the field pin_length was
replaced by the information whether or not that key is
authenticated;
* Still on that structure, it was added information about the role in
which the key should be used, e.g. a key marked as master should
only be used when the host is in the master role;
* More specific types for each type and role of key, previously it was
used the address field of the key to indentify the role of the key.
* The address type of the remote is sent with the LTK, this information
will be useful for userspace when recreating the device from storage.
Marcel, as I changed the key format in the patch "Bluetooth: Add
structures for the new LTK exchange messages" I decided to remove your
Ack from it.
Cheers,
--
Vinicius Costa Gomes (8):
Bluetooth: Add structures for the new LTK exchange messages
Bluetooth: Rename smp_key_size to enc_key_size
Bluetooth: Add new structures for handling SMP Long Term Keys
Bluetooth: Use the updated key structures for handling LTKs
Bluetooth: Add MGMT handlers for dealing with SMP LTK's
Bluetooth: Add support for removing LTK's when pairing is removed
Bluetooth: Clean up structures left unused
Bluetooth: Add support for notifying userspace of new LTK's
include/net/bluetooth/hci.h | 9 ++--
include/net/bluetooth/hci_core.h | 35 +++++++------
include/net/bluetooth/mgmt.h | 22 ++++++++
include/net/bluetooth/smp.h | 2 +-
net/bluetooth/hci_core.c | 111 ++++++++++++++++++++++++--------------
net/bluetooth/hci_event.c | 9 +++-
net/bluetooth/mgmt.c | 88 ++++++++++++++++++++++++++++++
net/bluetooth/smp.c | 50 ++++++++++-------
8 files changed, 241 insertions(+), 85 deletions(-)
--
1.7.8.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 1/8] Bluetooth: Add structures for the new LTK exchange messages
2012-01-13 19:39 [PATCH 0/8] New MGMT messages for SMP Long Term Keys Vinicius Costa Gomes
@ 2012-01-13 19:39 ` Vinicius Costa Gomes
2012-01-13 20:37 ` Brian Gix
2012-01-13 19:39 ` [PATCH 2/8] Bluetooth: Rename smp_key_size to enc_key_size Vinicius Costa Gomes
` (6 subsequent siblings)
7 siblings, 1 reply; 20+ messages in thread
From: Vinicius Costa Gomes @ 2012-01-13 19:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
This defines two new messages, one event that will inform
userspace that a new Long Term Key was exchanged and one that
will allow userspace to load LTKs into the kernel.
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
include/net/bluetooth/mgmt.h | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index be65d34..994b551 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -288,6 +288,22 @@ struct mgmt_cp_unblock_device {
bdaddr_t bdaddr;
} __packed;
+struct mgmt_ltk_info {
+ struct mgmt_addr_info addr;
+ __u8 authenticated;
+ __u8 master;
+ __u8 enc_size;
+ __le16 ediv;
+ __u8 rand[8];
+ __u8 val[16];
+} __packed;
+
+#define MGMT_OP_LOAD_LONG_TERM_KEYS 0x0026
+struct mgmt_cp_load_long_term_keys {
+ __u16 key_count;
+ struct mgmt_ltk_info keys[0];
+} __packed;
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
@@ -388,3 +404,9 @@ struct mgmt_ev_device_blocked {
struct mgmt_ev_device_unblocked {
bdaddr_t bdaddr;
} __packed;
+
+#define MGMT_EV_NEW_LONG_TERM_KEY 0x0016
+struct mgmt_ev_new_long_term_key {
+ __u8 store_hint;
+ struct mgmt_ltk_info key;
+} __packed;
--
1.7.8.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 2/8] Bluetooth: Rename smp_key_size to enc_key_size
2012-01-13 19:39 [PATCH 0/8] New MGMT messages for SMP Long Term Keys Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 1/8] Bluetooth: Add structures for the new LTK exchange messages Vinicius Costa Gomes
@ 2012-01-13 19:39 ` Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 3/8] Bluetooth: Add new structures for handling SMP Long Term Keys Vinicius Costa Gomes
` (5 subsequent siblings)
7 siblings, 0 replies; 20+ messages in thread
From: Vinicius Costa Gomes @ 2012-01-13 19:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
This makes clear that this is the size of the key used to
encrypt the link.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
include/net/bluetooth/smp.h | 2 +-
net/bluetooth/smp.c | 18 +++++++++---------
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index aeaf5fa..7b3acdd 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -127,7 +127,7 @@ struct smp_chan {
u8 rrnd[16]; /* SMP Pairing Random (remote) */
u8 pcnf[16]; /* SMP Pairing Confirm */
u8 tk[16]; /* SMP Temporary Key */
- u8 smp_key_size;
+ u8 enc_key_size;
unsigned long smp_flags;
struct crypto_blkcipher *tfm;
struct work_struct confirm;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 65a9024..b7f2fd1 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -250,7 +250,7 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
(max_key_size < SMP_MIN_ENC_KEY_SIZE))
return SMP_ENC_KEY_SIZE;
- smp->smp_key_size = max_key_size;
+ smp->enc_key_size = max_key_size;
return 0;
}
@@ -446,8 +446,8 @@ static void random_work(struct work_struct *work)
smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, key);
swap128(key, stk);
- memset(stk + smp->smp_key_size, 0,
- SMP_MAX_ENC_KEY_SIZE - smp->smp_key_size);
+ memset(stk + smp->enc_key_size, 0,
+ SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend)) {
reason = SMP_UNSPECIFIED;
@@ -455,7 +455,7 @@ static void random_work(struct work_struct *work)
}
hci_le_start_enc(hcon, ediv, rand, stk);
- hcon->enc_key_size = smp->smp_key_size;
+ hcon->enc_key_size = smp->enc_key_size;
} else {
u8 stk[16], r[16], rand[8];
__le16 ediv;
@@ -469,10 +469,10 @@ static void random_work(struct work_struct *work)
smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, key);
swap128(key, stk);
- memset(stk + smp->smp_key_size, 0,
- SMP_MAX_ENC_KEY_SIZE - smp->smp_key_size);
+ memset(stk + smp->enc_key_size, 0,
+ SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
- hci_add_ltk(hcon->hdev, 0, conn->dst, smp->smp_key_size,
+ hci_add_ltk(hcon->hdev, 0, conn->dst, smp->enc_key_size,
ediv, rand, stk);
}
@@ -820,7 +820,7 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
skb_pull(skb, sizeof(*rp));
- hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->smp_key_size,
+ hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->enc_key_size,
rp->ediv, rp->rand, smp->tk);
smp_distribute_keys(conn, 1);
@@ -941,7 +941,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
- hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->smp_key_size,
+ hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->enc_key_size,
ediv, ident.rand, enc.ltk);
ident.ediv = cpu_to_le16(ediv);
--
1.7.8.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 3/8] Bluetooth: Add new structures for handling SMP Long Term Keys
2012-01-13 19:39 [PATCH 0/8] New MGMT messages for SMP Long Term Keys Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 1/8] Bluetooth: Add structures for the new LTK exchange messages Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 2/8] Bluetooth: Rename smp_key_size to enc_key_size Vinicius Costa Gomes
@ 2012-01-13 19:39 ` Vinicius Costa Gomes
2012-01-13 20:43 ` Brian Gix
2012-01-13 19:39 ` [PATCH 4/8] Bluetooth: Use the updated key structures for handling LTKs Vinicius Costa Gomes
` (4 subsequent siblings)
7 siblings, 1 reply; 20+ messages in thread
From: Vinicius Costa Gomes @ 2012-01-13 19:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
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>
---
include/net/bluetooth/hci.h | 5 +++++
include/net/bluetooth/hci_core.h | 15 +++++++++++++++
net/bluetooth/hci_core.c | 31 +++++++++++++++++++++++++++++++
3 files changed, 51 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 8499307..3056115 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -273,6 +273,11 @@ enum {
#define HCI_LK_SMP_LTK 0x81
#define HCI_LK_SMP_IRK 0x82
#define HCI_LK_SMP_CSRK 0x83
+/* The spec doesn't define types for SMP keys, the _MASTER suffix is implied */
+#define HCI_SMP_STK 0x80
+#define HCI_SMP_STK_SLAVE 0x81
+#define HCI_SMP_LTK 0x82
+#define HCI_SMP_LTK_SLAVE 0x83
/* ---- HCI Error Codes ---- */
#define HCI_ERROR_AUTH_FAILURE 0x05
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 59e3541..9d77a66 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -88,6 +88,18 @@ struct bt_uuid {
u8 svc_hint;
};
+struct smp_ltk {
+ struct list_head list;
+ bdaddr_t bdaddr;
+ u8 bdaddr_type;
+ u8 authenticated;
+ u8 type;
+ u8 enc_size;
+ __le16 ediv;
+ u8 rand[8];
+ u8 val[16];
+} __packed;
+
struct key_master_id {
__le16 ediv;
u8 rand[8];
@@ -240,6 +252,8 @@ struct hci_dev {
struct list_head link_keys;
+ struct list_head ltks;
+
struct list_head remote_oob_data;
struct list_head adv_entries;
@@ -643,6 +657,7 @@ struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
+int hci_smp_ltks_clear(struct hci_dev *hdev);
int hci_remote_oob_data_clear(struct hci_dev *hdev);
struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index a7b7200..3b5902d 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)
return 0;
}
+int hci_smp_ltks_clear(struct hci_dev *hdev)
+{
+ struct smp_ltk *k, *tmp;
+
+ list_for_each_entry_safe(k, tmp, &hdev->ltks, list) {
+ list_del(&k->list);
+ kfree(k);
+ }
+
+ return 0;
+}
+
struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
{
struct link_key *k;
@@ -1355,6 +1367,23 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
return 0;
}
+int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+ struct smp_ltk *k, *tmp;
+
+ list_for_each_entry_safe(k, tmp, &hdev->ltks, list) {
+ if (bacmp(bdaddr, &k->bdaddr))
+ continue;
+
+ BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
+
+ list_del(&k->list);
+ kfree(k);
+ }
+
+ return 0;
+}
+
/* HCI command timer function */
static void hci_cmd_timer(unsigned long arg)
{
@@ -1638,6 +1667,7 @@ int hci_register_dev(struct hci_dev *hdev)
INIT_LIST_HEAD(&hdev->uuids);
INIT_LIST_HEAD(&hdev->link_keys);
+ INIT_LIST_HEAD(&hdev->ltks);
INIT_LIST_HEAD(&hdev->remote_oob_data);
@@ -1739,6 +1769,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
hci_blacklist_clear(hdev);
hci_uuids_clear(hdev);
hci_link_keys_clear(hdev);
+ hci_smp_ltks_clear(hdev);
hci_remote_oob_data_clear(hdev);
hci_adv_entries_clear(hdev);
hci_dev_unlock(hdev);
--
1.7.8.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 4/8] Bluetooth: Use the updated key structures for handling LTKs
2012-01-13 19:39 [PATCH 0/8] New MGMT messages for SMP Long Term Keys Vinicius Costa Gomes
` (2 preceding siblings ...)
2012-01-13 19:39 ` [PATCH 3/8] Bluetooth: Add new structures for handling SMP Long Term Keys Vinicius Costa Gomes
@ 2012-01-13 19:39 ` Vinicius Costa Gomes
2012-01-13 20:52 ` Brian Gix
2012-01-13 19:39 ` [PATCH 5/8] Bluetooth: Add MGMT handlers for dealing with SMP LTK's Vinicius Costa Gomes
` (3 subsequent siblings)
7 siblings, 1 reply; 20+ messages in thread
From: Vinicius Costa Gomes @ 2012-01-13 19:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
This updates all the users of the older way, that was using the
link_keys list to store the SMP keys, to use the new way.
This includes defining new types for the keys, we have a type for each
combination of STK/LTK and Master/Slave.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 11 +++--
net/bluetooth/hci_core.c | 79 ++++++++++++++++++--------------------
net/bluetooth/hci_event.c | 9 +++-
net/bluetooth/smp.c | 38 +++++++++++-------
4 files changed, 73 insertions(+), 64 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 9d77a66..7ce25ad 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -651,12 +651,13 @@ int hci_link_keys_clear(struct hci_dev *hdev);
struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
-struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
-struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
- bdaddr_t *bdaddr, u8 type);
-int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
- u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
+struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
+int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
+ int new_key, u8 authenticated, u8 tk[16],
+ u8 enc_size, u16 ediv, u8 rand[8]);
int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
+struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ u8 addr_type);
int hci_smp_ltks_clear(struct hci_dev *hdev);
int hci_remote_oob_data_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 3b5902d..5f41e74 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1222,41 +1222,40 @@ static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
return 0;
}
-struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
+/* If the returned key is a STK it should be free'd by the caller */
+struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
{
- struct link_key *k;
-
- list_for_each_entry(k, &hdev->link_keys, list) {
- struct key_master_id *id;
+ struct smp_ltk *k, *tmp;
- if (k->type != HCI_LK_SMP_LTK)
+ list_for_each_entry_safe(k, tmp, &hdev->ltks, list) {
+ if (k->ediv != ediv ||
+ memcmp(rand, k->rand, sizeof(k->rand)))
continue;
- if (k->dlen != sizeof(*id))
- continue;
+ /* The STK should only be used once, no need to keep it */
+ if (k->type & HCI_SMP_STK)
+ list_del(&k->list);
- id = (void *) &k->data;
- if (id->ediv == ediv &&
- (memcmp(rand, id->rand, sizeof(id->rand)) == 0))
- return k;
+ return k;
}
return NULL;
}
EXPORT_SYMBOL(hci_find_ltk);
-struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
- bdaddr_t *bdaddr, u8 type)
+struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ u8 addr_type)
{
- struct link_key *k;
+ struct smp_ltk *k;
- list_for_each_entry(k, &hdev->link_keys, list)
- if (k->type == type && bacmp(bdaddr, &k->bdaddr) == 0)
+ list_for_each_entry(k, &hdev->ltks, list)
+ if (addr_type == k->bdaddr_type &&
+ bacmp(bdaddr, &k->bdaddr) == 0)
return k;
return NULL;
}
-EXPORT_SYMBOL(hci_find_link_key_type);
+EXPORT_SYMBOL(hci_find_ltk_addr);
int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
@@ -1313,40 +1312,36 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
return 0;
}
-int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
- u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16])
+int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
+ int new_key, u8 authenticated, u8 tk[16],
+ u8 enc_size, u16 ediv, u8 rand[8])
{
- struct link_key *key, *old_key;
- struct key_master_id *id;
- u8 old_key_type;
+ struct smp_ltk *key, *old_key;
- BT_DBG("%s addr %s", hdev->name, batostr(bdaddr));
+ if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
+ return 0;
- old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK);
- if (old_key) {
+ old_key = hci_find_ltk_addr(hdev, bdaddr, addr_type);
+ if (old_key)
key = old_key;
- old_key_type = old_key->type;
- } else {
- key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC);
+ else {
+ key = kzalloc(sizeof(*key), GFP_ATOMIC);
if (!key)
return -ENOMEM;
- list_add(&key->list, &hdev->link_keys);
- old_key_type = 0xff;
+ list_add(&key->list, &hdev->ltks);
}
- key->dlen = sizeof(*id);
-
bacpy(&key->bdaddr, bdaddr);
- memcpy(key->val, ltk, sizeof(key->val));
- key->type = HCI_LK_SMP_LTK;
- key->pin_len = key_size;
-
- id = (void *) &key->data;
- id->ediv = ediv;
- memcpy(id->rand, rand, sizeof(id->rand));
+ key->bdaddr_type = addr_type;
+ memcpy(key->val, tk, sizeof(key->val));
+ key->authenticated = authenticated;
+ key->ediv = ediv;
+ key->enc_size = enc_size;
+ key->type = type;
+ memcpy(key->rand, rand, sizeof(key->rand));
- if (new_key)
- mgmt_new_link_key(hdev, key, old_key_type);
+ if (!new_key)
+ return 0;
return 0;
}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 94a9ca2..750fc0c 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3227,7 +3227,7 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
struct hci_cp_le_ltk_reply cp;
struct hci_cp_le_ltk_neg_reply neg;
struct hci_conn *conn;
- struct link_key *ltk;
+ struct smp_ltk *ltk;
BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
@@ -3243,10 +3243,15 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
cp.handle = cpu_to_le16(conn->handle);
- conn->pin_length = ltk->pin_len;
+
+ if (ltk->authenticated)
+ conn->sec_level = BT_SECURITY_HIGH;
hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
+ if (ltk->type & HCI_SMP_STK)
+ kfree(ltk);
+
hci_dev_unlock(hdev);
return;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index b7f2fd1..7bc82e4 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -472,8 +472,9 @@ static void random_work(struct work_struct *work)
memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
- hci_add_ltk(hcon->hdev, 0, conn->dst, smp->enc_key_size,
- ediv, rand, stk);
+ hci_add_ltk(hcon->hdev, conn->dst, hcon->dst_type,
+ HCI_SMP_STK_SLAVE, 0, 0, stk,
+ smp->enc_key_size, ediv, rand);
}
return;
@@ -698,12 +699,10 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
static u8 smp_ltk_encrypt(struct l2cap_conn *conn)
{
- struct link_key *key;
- struct key_master_id *master;
+ struct smp_ltk *key;
struct hci_conn *hcon = conn->hcon;
- key = hci_find_link_key_type(hcon->hdev, conn->dst,
- HCI_LK_SMP_LTK);
+ key = hci_find_ltk_addr(hcon->hdev, conn->dst, hcon->dst_type);
if (!key)
return 0;
@@ -711,10 +710,8 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn)
&hcon->pend))
return 1;
- master = (void *) key->data;
- hci_le_start_enc(hcon, master->ediv, master->rand,
- key->val);
- hcon->enc_key_size = key->pin_len;
+ hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
+ hcon->enc_key_size = key->enc_size;
return 1;
@@ -817,13 +814,19 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct smp_cmd_master_ident *rp = (void *) skb->data;
struct smp_chan *smp = conn->smp_chan;
+ struct hci_dev *hdev = conn->hcon->hdev;
+ struct hci_conn *hcon = conn->hcon;
+ u8 authenticated;
skb_pull(skb, sizeof(*rp));
- hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->enc_key_size,
- rp->ediv, rp->rand, smp->tk);
-
+ hci_dev_lock(hdev);
+ authenticated = (conn->hcon->sec_level == BT_SECURITY_HIGH);
+ hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
+ HCI_SMP_LTK, 1, authenticated, smp->tk,
+ smp->enc_key_size, rp->ediv, rp->rand);
smp_distribute_keys(conn, 1);
+ hci_dev_unlock(hdev);
return 0;
}
@@ -933,6 +936,8 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
if (*keydist & SMP_DIST_ENC_KEY) {
struct smp_cmd_encrypt_info enc;
struct smp_cmd_master_ident ident;
+ struct hci_conn *hcon = conn->hcon;
+ u8 authenticated;
__le16 ediv;
get_random_bytes(enc.ltk, sizeof(enc.ltk));
@@ -941,8 +946,11 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
- hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->enc_key_size,
- ediv, ident.rand, enc.ltk);
+ authenticated = hcon->sec_level == BT_SECURITY_HIGH;
+ hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
+ HCI_SMP_LTK_SLAVE, 1, authenticated,
+ enc.ltk, smp->enc_key_size,
+ ediv, ident.rand);
ident.ediv = cpu_to_le16(ediv);
--
1.7.8.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 5/8] Bluetooth: Add MGMT handlers for dealing with SMP LTK's
2012-01-13 19:39 [PATCH 0/8] New MGMT messages for SMP Long Term Keys Vinicius Costa Gomes
` (3 preceding siblings ...)
2012-01-13 19:39 ` [PATCH 4/8] Bluetooth: Use the updated key structures for handling LTKs Vinicius Costa Gomes
@ 2012-01-13 19:39 ` Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 6/8] Bluetooth: Add support for removing LTK's when pairing is removed Vinicius Costa Gomes
` (2 subsequent siblings)
7 siblings, 0 replies; 20+ messages in thread
From: Vinicius Costa Gomes @ 2012-01-13 19:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
This adds a method to notify that a new LTK is available and
a handler to store keys coming from userspace into the kernel LTK
list.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 2 +
net/bluetooth/mgmt.c | 82 ++++++++++++++++++++++++++++++++++++++
2 files changed, 84 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 7ce25ad..34ccaf4 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -949,6 +949,8 @@ int mgmt_discovering(struct hci_dev *hdev, u8 discovering);
int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr);
int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr);
+int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent);
+
/* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 2dae2e8..3cbee32 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2179,6 +2179,62 @@ done:
return err;
}
+static int load_long_term_keys(struct sock *sk, u16 index,
+ unsigned char *data, u16 len)
+{
+ struct hci_dev *hdev;
+ struct mgmt_cp_load_long_term_keys *cp;
+ u16 key_count, expected_len;
+ int i;
+
+ cp = (void *) data;
+
+ if (len < sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS,
+ EINVAL);
+
+ key_count = get_unaligned_le16(&cp->key_count);
+
+ expected_len = sizeof(*cp) + key_count *
+ sizeof(struct mgmt_ltk_info);
+ if (expected_len != len) {
+ BT_ERR("load_keys: expected %u bytes, got %u bytes",
+ len, expected_len);
+ return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS,
+ EINVAL);
+ }
+
+ hdev = hci_dev_get(index);
+ if (!hdev)
+ return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS,
+ ENODEV);
+
+ BT_DBG("hci%u key_count %u", index, key_count);
+
+ hci_dev_lock(hdev);
+
+ hci_smp_ltks_clear(hdev);
+
+ for (i = 0; i < key_count; i++) {
+ struct mgmt_ltk_info *key = &cp->keys[i];
+ u8 type;
+
+ if (key->master)
+ type = HCI_SMP_LTK;
+ else
+ type = HCI_SMP_LTK_SLAVE;
+
+ hci_add_ltk(hdev, &key->addr.bdaddr, key->addr.type,
+ type, 0, key->authenticated, key->val,
+ key->enc_size, key->ediv, key->rand);
+ }
+
+ hci_dev_unlock(hdev);
+ hci_dev_put(hdev);
+
+ return 0;
+}
+
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
{
unsigned char *buf;
@@ -2311,6 +2367,9 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
case MGMT_OP_UNBLOCK_DEVICE:
err = unblock_device(sk, index, buf + sizeof(*hdr), len);
break;
+ case MGMT_OP_LOAD_LONG_TERM_KEYS:
+ err = load_long_term_keys(sk, index, buf + sizeof(*hdr), len);
+ break;
default:
BT_DBG("Unknown op %u", opcode);
err = cmd_status(sk, index, opcode,
@@ -2464,6 +2523,29 @@ int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
return mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL);
}
+int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent)
+{
+ struct mgmt_ev_new_long_term_key ev;
+
+ memset(&ev, 0, sizeof(ev));
+
+ ev.store_hint = persistent;
+ bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
+ ev.key.addr.type = key->bdaddr_type;
+ ev.key.authenticated = key->authenticated;
+ ev.key.enc_size = key->enc_size;
+ ev.key.ediv = key->ediv;
+
+ if (key->type == HCI_SMP_LTK)
+ ev.key.master = 1;
+
+ memcpy(ev.key.rand, key->rand, sizeof(key->rand));
+ memcpy(ev.key.val, key->val, sizeof(key->val));
+
+ return mgmt_event(MGMT_EV_NEW_LONG_TERM_KEY, hdev,
+ &ev, sizeof(ev), NULL);
+}
+
int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type)
{
--
1.7.8.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 6/8] Bluetooth: Add support for removing LTK's when pairing is removed
2012-01-13 19:39 [PATCH 0/8] New MGMT messages for SMP Long Term Keys Vinicius Costa Gomes
` (4 preceding siblings ...)
2012-01-13 19:39 ` [PATCH 5/8] Bluetooth: Add MGMT handlers for dealing with SMP LTK's Vinicius Costa Gomes
@ 2012-01-13 19:39 ` Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 7/8] Bluetooth: Clean up structures left unused Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 8/8] Bluetooth: Add support for notifying userspace of new LTK's Vinicius Costa Gomes
7 siblings, 0 replies; 20+ messages in thread
From: Vinicius Costa Gomes @ 2012-01-13 19:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
Instead of having a separated command for removing SMP keys, we use the
Remove Keys command to remove *all* keys.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/mgmt.c | 6 ++++++
2 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 34ccaf4..4ab8019 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -658,6 +658,7 @@ int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 addr_type);
+int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_smp_ltks_clear(struct hci_dev *hdev);
int hci_remote_oob_data_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 3cbee32..f244349 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1113,6 +1113,12 @@ static int remove_keys(struct sock *sk, u16 index, unsigned char *data,
bacpy(&rp.bdaddr, &cp->bdaddr);
rp.status = MGMT_STATUS_FAILED;
+ err = hci_remove_ltk(hdev, &cp->bdaddr);
+ if (err < 0) {
+ err = cmd_status(sk, index, MGMT_OP_REMOVE_KEYS, -err);
+ goto unlock;
+ }
+
err = hci_remove_link_key(hdev, &cp->bdaddr);
if (err < 0) {
rp.status = MGMT_STATUS_NOT_PAIRED;
--
1.7.8.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 7/8] Bluetooth: Clean up structures left unused
2012-01-13 19:39 [PATCH 0/8] New MGMT messages for SMP Long Term Keys Vinicius Costa Gomes
` (5 preceding siblings ...)
2012-01-13 19:39 ` [PATCH 6/8] Bluetooth: Add support for removing LTK's when pairing is removed Vinicius Costa Gomes
@ 2012-01-13 19:39 ` Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 8/8] Bluetooth: Add support for notifying userspace of new LTK's Vinicius Costa Gomes
7 siblings, 0 replies; 20+ messages in thread
From: Vinicius Costa Gomes @ 2012-01-13 19:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
With the use of the new structures and lists for the SMP LTK's
we may remove some code that is now unused. No need to have extra
fields of information inside link_key now that it is only used
for Link Keys.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
include/net/bluetooth/hci.h | 4 ----
include/net/bluetooth/hci_core.h | 16 ----------------
2 files changed, 0 insertions(+), 20 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 3056115..e12b719 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -269,10 +269,6 @@ enum {
#define HCI_LK_UNAUTH_COMBINATION 0x04
#define HCI_LK_AUTH_COMBINATION 0x05
#define HCI_LK_CHANGED_COMBINATION 0x06
-/* The spec doesn't define types for SMP keys */
-#define HCI_LK_SMP_LTK 0x81
-#define HCI_LK_SMP_IRK 0x82
-#define HCI_LK_SMP_CSRK 0x83
/* The spec doesn't define types for SMP keys, the _MASTER suffix is implied */
#define HCI_SMP_STK 0x80
#define HCI_SMP_STK_SLAVE 0x81
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 4ab8019..faf987e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -100,28 +100,12 @@ struct smp_ltk {
u8 val[16];
} __packed;
-struct key_master_id {
- __le16 ediv;
- u8 rand[8];
-} __packed;
-
-struct link_key_data {
- bdaddr_t bdaddr;
- u8 type;
- u8 val[16];
- u8 pin_len;
- u8 dlen;
- u8 data[0];
-} __packed;
-
struct link_key {
struct list_head list;
bdaddr_t bdaddr;
u8 type;
u8 val[16];
u8 pin_len;
- u8 dlen;
- u8 data[0];
};
struct oob_data {
--
1.7.8.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 8/8] Bluetooth: Add support for notifying userspace of new LTK's
2012-01-13 19:39 [PATCH 0/8] New MGMT messages for SMP Long Term Keys Vinicius Costa Gomes
` (6 preceding siblings ...)
2012-01-13 19:39 ` [PATCH 7/8] Bluetooth: Clean up structures left unused Vinicius Costa Gomes
@ 2012-01-13 19:39 ` Vinicius Costa Gomes
7 siblings, 0 replies; 20+ messages in thread
From: Vinicius Costa Gomes @ 2012-01-13 19:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
If we want to have proper pairing support over LE we need to
inform userspace that a new LTK is available, so userspace
can store that key permanently.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
net/bluetooth/hci_core.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 5f41e74..ffb66a1 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1343,6 +1343,9 @@ int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
if (!new_key)
return 0;
+ if (type & HCI_SMP_LTK)
+ mgmt_new_ltk(hdev, key, 1);
+
return 0;
}
--
1.7.8.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 1/8] Bluetooth: Add structures for the new LTK exchange messages
2012-01-13 19:39 ` [PATCH 1/8] Bluetooth: Add structures for the new LTK exchange messages Vinicius Costa Gomes
@ 2012-01-13 20:37 ` Brian Gix
2012-01-13 20:40 ` Vinicius Costa Gomes
0 siblings, 1 reply; 20+ messages in thread
From: Brian Gix @ 2012-01-13 20:37 UTC (permalink / raw)
To: Vinicius Costa Gomes; +Cc: linux-bluetooth
Hi Vinicius,
On 1/13/2012 11:39 AM, Vinicius Costa Gomes wrote:
> This defines two new messages, one event that will inform
> userspace that a new Long Term Key was exchanged and one that
> will allow userspace to load LTKs into the kernel.
>
> Acked-by: Marcel Holtmann<marcel@holtmann.org>
> Signed-off-by: Vinicius Costa Gomes<vinicius.gomes@openbossa.org>
> ---
> include/net/bluetooth/mgmt.h | 22 ++++++++++++++++++++++
> 1 files changed, 22 insertions(+), 0 deletions(-)
>
> diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
> index be65d34..994b551 100644
> --- a/include/net/bluetooth/mgmt.h
> +++ b/include/net/bluetooth/mgmt.h
> @@ -288,6 +288,22 @@ struct mgmt_cp_unblock_device {
> bdaddr_t bdaddr;
> } __packed;
>
> +struct mgmt_ltk_info {
> + struct mgmt_addr_info addr;
> + __u8 authenticated;
> + __u8 master;
> + __u8 enc_size;
> + __le16 ediv;
> + __u8 rand[8];
> + __u8 val[16];
> +} __packed;
> +
> +#define MGMT_OP_LOAD_LONG_TERM_KEYS 0x0026
> +struct mgmt_cp_load_long_term_keys {
> + __u16 key_count;
> + struct mgmt_ltk_info keys[0];
> +} __packed;
> +
I think all multi-octet values should be going over the MGMT interface
in "network order", so shouldn't key_count here be __le16 ?
> #define MGMT_EV_CMD_COMPLETE 0x0001
> struct mgmt_ev_cmd_complete {
> __le16 opcode;
> @@ -388,3 +404,9 @@ struct mgmt_ev_device_blocked {
> struct mgmt_ev_device_unblocked {
> bdaddr_t bdaddr;
> } __packed;
> +
> +#define MGMT_EV_NEW_LONG_TERM_KEY 0x0016
> +struct mgmt_ev_new_long_term_key {
> + __u8 store_hint;
> + struct mgmt_ltk_info key;
> +} __packed;
--
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/8] Bluetooth: Add structures for the new LTK exchange messages
2012-01-13 20:37 ` Brian Gix
@ 2012-01-13 20:40 ` Vinicius Costa Gomes
2012-01-17 0:14 ` Vinicius Costa Gomes
0 siblings, 1 reply; 20+ messages in thread
From: Vinicius Costa Gomes @ 2012-01-13 20:40 UTC (permalink / raw)
To: Brian Gix; +Cc: linux-bluetooth
Hi Brian,
On 12:37 Fri 13 Jan, Brian Gix wrote:
> Hi Vinicius,
>
> On 1/13/2012 11:39 AM, Vinicius Costa Gomes wrote:
> >This defines two new messages, one event that will inform
> >userspace that a new Long Term Key was exchanged and one that
> >will allow userspace to load LTKs into the kernel.
> >
> >Acked-by: Marcel Holtmann<marcel@holtmann.org>
> >Signed-off-by: Vinicius Costa Gomes<vinicius.gomes@openbossa.org>
> >---
> > include/net/bluetooth/mgmt.h | 22 ++++++++++++++++++++++
> > 1 files changed, 22 insertions(+), 0 deletions(-)
> >
> >diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
> >index be65d34..994b551 100644
> >--- a/include/net/bluetooth/mgmt.h
> >+++ b/include/net/bluetooth/mgmt.h
> >@@ -288,6 +288,22 @@ struct mgmt_cp_unblock_device {
> > bdaddr_t bdaddr;
> > } __packed;
> >
> >+struct mgmt_ltk_info {
> >+ struct mgmt_addr_info addr;
> >+ __u8 authenticated;
> >+ __u8 master;
> >+ __u8 enc_size;
> >+ __le16 ediv;
> >+ __u8 rand[8];
> >+ __u8 val[16];
> >+} __packed;
> >+
> >+#define MGMT_OP_LOAD_LONG_TERM_KEYS 0x0026
> >+struct mgmt_cp_load_long_term_keys {
> >+ __u16 key_count;
> >+ struct mgmt_ltk_info keys[0];
> >+} __packed;
> >+
>
> I think all multi-octet values should be going over the MGMT
> interface in "network order", so shouldn't key_count here be __le16
> ?
>
You are right. Going to fix it, thanks. It was a leftover from the last
version of these patches.
>
>
>
> > #define MGMT_EV_CMD_COMPLETE 0x0001
> > struct mgmt_ev_cmd_complete {
> > __le16 opcode;
> >@@ -388,3 +404,9 @@ struct mgmt_ev_device_blocked {
> > struct mgmt_ev_device_unblocked {
> > bdaddr_t bdaddr;
> > } __packed;
> >+
> >+#define MGMT_EV_NEW_LONG_TERM_KEY 0x0016
> >+struct mgmt_ev_new_long_term_key {
> >+ __u8 store_hint;
> >+ struct mgmt_ltk_info key;
> >+} __packed;
>
>
> --
> Brian Gix
> bgix@codeaurora.org
> Employee of Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
Cheers,
--
Vinicius
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 3/8] Bluetooth: Add new structures for handling SMP Long Term Keys
2012-01-13 19:39 ` [PATCH 3/8] Bluetooth: Add new structures for handling SMP Long Term Keys Vinicius Costa Gomes
@ 2012-01-13 20:43 ` Brian Gix
0 siblings, 0 replies; 20+ messages in thread
From: Brian Gix @ 2012-01-13 20:43 UTC (permalink / raw)
To: Vinicius Costa Gomes; +Cc: linux-bluetooth
Hi Vinicius,
On 1/13/2012 11:39 AM, Vinicius Costa Gomes wrote:
> 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>
> ---
> include/net/bluetooth/hci.h | 5 +++++
> include/net/bluetooth/hci_core.h | 15 +++++++++++++++
> net/bluetooth/hci_core.c | 31 +++++++++++++++++++++++++++++++
> 3 files changed, 51 insertions(+), 0 deletions(-)
>
> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> index 8499307..3056115 100644
> --- a/include/net/bluetooth/hci.h
> +++ b/include/net/bluetooth/hci.h
> @@ -273,6 +273,11 @@ enum {
> #define HCI_LK_SMP_LTK 0x81
> #define HCI_LK_SMP_IRK 0x82
> #define HCI_LK_SMP_CSRK 0x83
> +/* The spec doesn't define types for SMP keys, the _MASTER suffix is implied */
> +#define HCI_SMP_STK 0x80
> +#define HCI_SMP_STK_SLAVE 0x81
> +#define HCI_SMP_LTK 0x82
> +#define HCI_SMP_LTK_SLAVE 0x83
This list should be contiguous, and you should probably remove the
others at the same time. I would also suggest adding MASTER and SLAVE
versions of CSRK and maybe IRK as well. (IRK is used differently, and
may not need a Master/Slave version, but it wouldn't hurt anything).
CSRK, when implimented will definitely need both Master and Slave versions.
>
> /* ---- HCI Error Codes ---- */
> #define HCI_ERROR_AUTH_FAILURE 0x05
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index 59e3541..9d77a66 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -88,6 +88,18 @@ struct bt_uuid {
> u8 svc_hint;
> };
>
> +struct smp_ltk {
> + struct list_head list;
> + bdaddr_t bdaddr;
> + u8 bdaddr_type;
> + u8 authenticated;
> + u8 type;
> + u8 enc_size;
> + __le16 ediv;
> + u8 rand[8];
> + u8 val[16];
> +} __packed;
> +
> struct key_master_id {
> __le16 ediv;
> u8 rand[8];
> @@ -240,6 +252,8 @@ struct hci_dev {
>
> struct list_head link_keys;
>
> + struct list_head ltks;
> +
> struct list_head remote_oob_data;
>
> struct list_head adv_entries;
> @@ -643,6 +657,7 @@ struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
> int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
> u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
> int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
> +int hci_smp_ltks_clear(struct hci_dev *hdev);
>
> int hci_remote_oob_data_clear(struct hci_dev *hdev);
> struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index a7b7200..3b5902d 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)
> return 0;
> }
>
> +int hci_smp_ltks_clear(struct hci_dev *hdev)
> +{
> + struct smp_ltk *k, *tmp;
> +
> + list_for_each_entry_safe(k, tmp,&hdev->ltks, list) {
> + list_del(&k->list);
> + kfree(k);
> + }
> +
> + return 0;
> +}
> +
> struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
> {
> struct link_key *k;
> @@ -1355,6 +1367,23 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
> return 0;
> }
>
> +int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
> +{
> + struct smp_ltk *k, *tmp;
> +
> + list_for_each_entry_safe(k, tmp,&hdev->ltks, list) {
> + if (bacmp(bdaddr,&k->bdaddr))
> + continue;
> +
> + BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
> +
> + list_del(&k->list);
> + kfree(k);
> + }
> +
> + return 0;
> +}
> +
> /* HCI command timer function */
> static void hci_cmd_timer(unsigned long arg)
> {
> @@ -1638,6 +1667,7 @@ int hci_register_dev(struct hci_dev *hdev)
> INIT_LIST_HEAD(&hdev->uuids);
>
> INIT_LIST_HEAD(&hdev->link_keys);
> + INIT_LIST_HEAD(&hdev->ltks);
>
> INIT_LIST_HEAD(&hdev->remote_oob_data);
>
> @@ -1739,6 +1769,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
> hci_blacklist_clear(hdev);
> hci_uuids_clear(hdev);
> hci_link_keys_clear(hdev);
> + hci_smp_ltks_clear(hdev);
> hci_remote_oob_data_clear(hdev);
> hci_adv_entries_clear(hdev);
> hci_dev_unlock(hdev);
--
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 4/8] Bluetooth: Use the updated key structures for handling LTKs
2012-01-13 19:39 ` [PATCH 4/8] Bluetooth: Use the updated key structures for handling LTKs Vinicius Costa Gomes
@ 2012-01-13 20:52 ` Brian Gix
2012-01-13 21:43 ` Vinicius Costa Gomes
0 siblings, 1 reply; 20+ messages in thread
From: Brian Gix @ 2012-01-13 20:52 UTC (permalink / raw)
To: Vinicius Costa Gomes; +Cc: linux-bluetooth
Hi Vinicius,
On 1/13/2012 11:39 AM, Vinicius Costa Gomes wrote:
> This updates all the users of the older way, that was using the
> link_keys list to store the SMP keys, to use the new way.
>
> This includes defining new types for the keys, we have a type for each
> combination of STK/LTK and Master/Slave.
>
> Signed-off-by: Vinicius Costa Gomes<vinicius.gomes@openbossa.org>
> ---
> include/net/bluetooth/hci_core.h | 11 +++--
> net/bluetooth/hci_core.c | 79 ++++++++++++++++++--------------------
> net/bluetooth/hci_event.c | 9 +++-
> net/bluetooth/smp.c | 38 +++++++++++-------
> 4 files changed, 73 insertions(+), 64 deletions(-)
>
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index 9d77a66..7ce25ad 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -651,12 +651,13 @@ int hci_link_keys_clear(struct hci_dev *hdev);
> struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
> int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
> bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
> -struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
> -struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
> - bdaddr_t *bdaddr, u8 type);
> -int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
> - u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
> +struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
> +int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
> + int new_key, u8 authenticated, u8 tk[16],
> + u8 enc_size, u16 ediv, u8 rand[8]);
> int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
> +struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
> + u8 addr_type);
> int hci_smp_ltks_clear(struct hci_dev *hdev);
>
> int hci_remote_oob_data_clear(struct hci_dev *hdev);
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index 3b5902d..5f41e74 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -1222,41 +1222,40 @@ static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
> return 0;
> }
>
> -struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
> +/* If the returned key is a STK it should be free'd by the caller */
> +struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
> {
> - struct link_key *k;
> -
> - list_for_each_entry(k,&hdev->link_keys, list) {
> - struct key_master_id *id;
> + struct smp_ltk *k, *tmp;
>
> - if (k->type != HCI_LK_SMP_LTK)
> + list_for_each_entry_safe(k, tmp,&hdev->ltks, list) {
> + if (k->ediv != ediv ||
> + memcmp(rand, k->rand, sizeof(k->rand)))
> continue;
>
> - if (k->dlen != sizeof(*id))
> - continue;
> + /* The STK should only be used once, no need to keep it */
> + if (k->type& HCI_SMP_STK)
> + list_del(&k->list);
Is HCI_SMP_STK a mask? Shouldn't this be an equality test?
>
> - id = (void *)&k->data;
> - if (id->ediv == ediv&&
> - (memcmp(rand, id->rand, sizeof(id->rand)) == 0))
> - return k;
> + return k;
> }
>
> return NULL;
> }
> EXPORT_SYMBOL(hci_find_ltk);
>
> -struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
> - bdaddr_t *bdaddr, u8 type)
> +struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
> + u8 addr_type)
> {
> - struct link_key *k;
> + struct smp_ltk *k;
>
> - list_for_each_entry(k,&hdev->link_keys, list)
> - if (k->type == type&& bacmp(bdaddr,&k->bdaddr) == 0)
> + list_for_each_entry(k,&hdev->ltks, list)
> + if (addr_type == k->bdaddr_type&&
> + bacmp(bdaddr,&k->bdaddr) == 0)
> return k;
>
> return NULL;
> }
> -EXPORT_SYMBOL(hci_find_link_key_type);
> +EXPORT_SYMBOL(hci_find_ltk_addr);
>
> int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
> bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
> @@ -1313,40 +1312,36 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
> return 0;
> }
>
> -int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
> - u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16])
> +int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
> + int new_key, u8 authenticated, u8 tk[16],
> + u8 enc_size, u16 ediv, u8 rand[8])
> {
> - struct link_key *key, *old_key;
> - struct key_master_id *id;
> - u8 old_key_type;
> + struct smp_ltk *key, *old_key;
>
> - BT_DBG("%s addr %s", hdev->name, batostr(bdaddr));
> + if (!(type& HCI_SMP_STK)&& !(type& HCI_SMP_LTK))
> + return 0;
And here.
>
> - old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK);
> - if (old_key) {
> + old_key = hci_find_ltk_addr(hdev, bdaddr, addr_type);
> + if (old_key)
> key = old_key;
> - old_key_type = old_key->type;
> - } else {
> - key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC);
> + else {
> + key = kzalloc(sizeof(*key), GFP_ATOMIC);
> if (!key)
> return -ENOMEM;
Looks like some whitespace issues.
> - list_add(&key->list,&hdev->link_keys);
> - old_key_type = 0xff;
> + list_add(&key->list,&hdev->ltks);
> }
>
> - key->dlen = sizeof(*id);
> -
> bacpy(&key->bdaddr, bdaddr);
> - memcpy(key->val, ltk, sizeof(key->val));
> - key->type = HCI_LK_SMP_LTK;
> - key->pin_len = key_size;
> -
> - id = (void *)&key->data;
> - id->ediv = ediv;
> - memcpy(id->rand, rand, sizeof(id->rand));
> + key->bdaddr_type = addr_type;
> + memcpy(key->val, tk, sizeof(key->val));
> + key->authenticated = authenticated;
> + key->ediv = ediv;
> + key->enc_size = enc_size;
> + key->type = type;
> + memcpy(key->rand, rand, sizeof(key->rand));
>
> - if (new_key)
> - mgmt_new_link_key(hdev, key, old_key_type);
> + if (!new_key)
> + return 0;
>
> return 0;
> }
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index 94a9ca2..750fc0c 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -3227,7 +3227,7 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
> struct hci_cp_le_ltk_reply cp;
> struct hci_cp_le_ltk_neg_reply neg;
> struct hci_conn *conn;
> - struct link_key *ltk;
> + struct smp_ltk *ltk;
>
> BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
>
> @@ -3243,10 +3243,15 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
>
> memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
> cp.handle = cpu_to_le16(conn->handle);
> - conn->pin_length = ltk->pin_len;
> +
> + if (ltk->authenticated)
> + conn->sec_level = BT_SECURITY_HIGH;
>
> hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp),&cp);
>
> + if (ltk->type& HCI_SMP_STK)
> + kfree(ltk);
> +
> hci_dev_unlock(hdev);
>
> return;
> diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> index b7f2fd1..7bc82e4 100644
> --- a/net/bluetooth/smp.c
> +++ b/net/bluetooth/smp.c
> @@ -472,8 +472,9 @@ static void random_work(struct work_struct *work)
> memset(stk + smp->enc_key_size, 0,
> SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
>
> - hci_add_ltk(hcon->hdev, 0, conn->dst, smp->enc_key_size,
> - ediv, rand, stk);
> + hci_add_ltk(hcon->hdev, conn->dst, hcon->dst_type,
> + HCI_SMP_STK_SLAVE, 0, 0, stk,
> + smp->enc_key_size, ediv, rand);
> }
>
> return;
> @@ -698,12 +699,10 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
>
> static u8 smp_ltk_encrypt(struct l2cap_conn *conn)
> {
> - struct link_key *key;
> - struct key_master_id *master;
> + struct smp_ltk *key;
> struct hci_conn *hcon = conn->hcon;
>
> - key = hci_find_link_key_type(hcon->hdev, conn->dst,
> - HCI_LK_SMP_LTK);
> + key = hci_find_ltk_addr(hcon->hdev, conn->dst, hcon->dst_type);
> if (!key)
> return 0;
>
> @@ -711,10 +710,8 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn)
> &hcon->pend))
> return 1;
>
> - master = (void *) key->data;
> - hci_le_start_enc(hcon, master->ediv, master->rand,
> - key->val);
> - hcon->enc_key_size = key->pin_len;
> + hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
> + hcon->enc_key_size = key->enc_size;
>
> return 1;
>
> @@ -817,13 +814,19 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
> {
> struct smp_cmd_master_ident *rp = (void *) skb->data;
> struct smp_chan *smp = conn->smp_chan;
> + struct hci_dev *hdev = conn->hcon->hdev;
> + struct hci_conn *hcon = conn->hcon;
> + u8 authenticated;
>
> skb_pull(skb, sizeof(*rp));
>
> - hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->enc_key_size,
> - rp->ediv, rp->rand, smp->tk);
> -
> + hci_dev_lock(hdev);
> + authenticated = (conn->hcon->sec_level == BT_SECURITY_HIGH);
> + hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
> + HCI_SMP_LTK, 1, authenticated, smp->tk,
> + smp->enc_key_size, rp->ediv, rp->rand);
> smp_distribute_keys(conn, 1);
> + hci_dev_unlock(hdev);
>
> return 0;
> }
> @@ -933,6 +936,8 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
> if (*keydist& SMP_DIST_ENC_KEY) {
> struct smp_cmd_encrypt_info enc;
> struct smp_cmd_master_ident ident;
> + struct hci_conn *hcon = conn->hcon;
> + u8 authenticated;
> __le16 ediv;
>
> get_random_bytes(enc.ltk, sizeof(enc.ltk));
> @@ -941,8 +946,11 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
>
> smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc),&enc);
>
> - hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->enc_key_size,
> - ediv, ident.rand, enc.ltk);
> + authenticated = hcon->sec_level == BT_SECURITY_HIGH;
> + hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
> + HCI_SMP_LTK_SLAVE, 1, authenticated,
> + enc.ltk, smp->enc_key_size,
> + ediv, ident.rand);
>
> ident.ediv = cpu_to_le16(ediv);
>
--
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 4/8] Bluetooth: Use the updated key structures for handling LTKs
2012-01-13 20:52 ` Brian Gix
@ 2012-01-13 21:43 ` Vinicius Costa Gomes
2012-01-17 0:17 ` Vinicius Costa Gomes
0 siblings, 1 reply; 20+ messages in thread
From: Vinicius Costa Gomes @ 2012-01-13 21:43 UTC (permalink / raw)
To: Brian Gix; +Cc: linux-bluetooth
On 12:52 Fri 13 Jan, Brian Gix wrote:
> Hi Vinicius,
>
> On 1/13/2012 11:39 AM, Vinicius Costa Gomes wrote:
> >This updates all the users of the older way, that was using the
> >link_keys list to store the SMP keys, to use the new way.
> >
> >This includes defining new types for the keys, we have a type for each
> >combination of STK/LTK and Master/Slave.
> >
> >Signed-off-by: Vinicius Costa Gomes<vinicius.gomes@openbossa.org>
> >---
> > include/net/bluetooth/hci_core.h | 11 +++--
> > net/bluetooth/hci_core.c | 79 ++++++++++++++++++--------------------
> > net/bluetooth/hci_event.c | 9 +++-
> > net/bluetooth/smp.c | 38 +++++++++++-------
> > 4 files changed, 73 insertions(+), 64 deletions(-)
> >
> >diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> >index 9d77a66..7ce25ad 100644
> >--- a/include/net/bluetooth/hci_core.h
> >+++ b/include/net/bluetooth/hci_core.h
> >@@ -651,12 +651,13 @@ int hci_link_keys_clear(struct hci_dev *hdev);
> > struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
> > int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
> > bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
> >-struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
> >-struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
> >- bdaddr_t *bdaddr, u8 type);
> >-int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
> >- u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
> >+struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
> >+int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
> >+ int new_key, u8 authenticated, u8 tk[16],
> >+ u8 enc_size, u16 ediv, u8 rand[8]);
> > int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
> >+struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
> >+ u8 addr_type);
> > int hci_smp_ltks_clear(struct hci_dev *hdev);
> >
> > int hci_remote_oob_data_clear(struct hci_dev *hdev);
> >diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> >index 3b5902d..5f41e74 100644
> >--- a/net/bluetooth/hci_core.c
> >+++ b/net/bluetooth/hci_core.c
> >@@ -1222,41 +1222,40 @@ static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
> > return 0;
> > }
> >
> >-struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
> >+/* If the returned key is a STK it should be free'd by the caller */
> >+struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
> > {
> >- struct link_key *k;
> >-
> >- list_for_each_entry(k,&hdev->link_keys, list) {
> >- struct key_master_id *id;
> >+ struct smp_ltk *k, *tmp;
> >
> >- if (k->type != HCI_LK_SMP_LTK)
> >+ list_for_each_entry_safe(k, tmp,&hdev->ltks, list) {
> >+ if (k->ediv != ediv ||
> >+ memcmp(rand, k->rand, sizeof(k->rand)))
> > continue;
> >
> >- if (k->dlen != sizeof(*id))
> >- continue;
> >+ /* The STK should only be used once, no need to keep it */
> >+ if (k->type& HCI_SMP_STK)
> >+ list_del(&k->list);
>
> Is HCI_SMP_STK a mask? Shouldn't this be an equality test?
I agree that this might be too "smart", but as the only difference
between the master and slave key is the last bit, using an "and" makes
the code a little shorter. If you think something more explicit is
preferable, I will fix it.
>
> >
> >- id = (void *)&k->data;
> >- if (id->ediv == ediv&&
> >- (memcmp(rand, id->rand, sizeof(id->rand)) == 0))
> >- return k;
> >+ return k;
> > }
> >
> > return NULL;
> > }
> > EXPORT_SYMBOL(hci_find_ltk);
> >
> >-struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
> >- bdaddr_t *bdaddr, u8 type)
> >+struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
> >+ u8 addr_type)
> > {
> >- struct link_key *k;
> >+ struct smp_ltk *k;
> >
> >- list_for_each_entry(k,&hdev->link_keys, list)
> >- if (k->type == type&& bacmp(bdaddr,&k->bdaddr) == 0)
> >+ list_for_each_entry(k,&hdev->ltks, list)
> >+ if (addr_type == k->bdaddr_type&&
> >+ bacmp(bdaddr,&k->bdaddr) == 0)
> > return k;
> >
> > return NULL;
> > }
> >-EXPORT_SYMBOL(hci_find_link_key_type);
> >+EXPORT_SYMBOL(hci_find_ltk_addr);
> >
> > int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
> > bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
> >@@ -1313,40 +1312,36 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
> > return 0;
> > }
> >
> >-int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
> >- u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16])
> >+int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
> >+ int new_key, u8 authenticated, u8 tk[16],
> >+ u8 enc_size, u16 ediv, u8 rand[8])
> > {
> >- struct link_key *key, *old_key;
> >- struct key_master_id *id;
> >- u8 old_key_type;
> >+ struct smp_ltk *key, *old_key;
> >
> >- BT_DBG("%s addr %s", hdev->name, batostr(bdaddr));
> >+ if (!(type& HCI_SMP_STK)&& !(type& HCI_SMP_LTK))
> >+ return 0;
>
> And here.
Same reason as above.
>
> >
> >- old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK);
> >- if (old_key) {
> >+ old_key = hci_find_ltk_addr(hdev, bdaddr, addr_type);
> >+ if (old_key)
> > key = old_key;
> >- old_key_type = old_key->type;
> >- } else {
> >- key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC);
> >+ else {
> >+ key = kzalloc(sizeof(*key), GFP_ATOMIC);
> > if (!key)
> > return -ENOMEM;
>
> Looks like some whitespace issues.
I couldn't find any problem here. But there was a problem in the
function declaration.
>
> >- list_add(&key->list,&hdev->link_keys);
> >- old_key_type = 0xff;
> >+ list_add(&key->list,&hdev->ltks);
> > }
> >
> >- key->dlen = sizeof(*id);
> >-
> > bacpy(&key->bdaddr, bdaddr);
> >- memcpy(key->val, ltk, sizeof(key->val));
> >- key->type = HCI_LK_SMP_LTK;
> >- key->pin_len = key_size;
> >-
> >- id = (void *)&key->data;
> >- id->ediv = ediv;
> >- memcpy(id->rand, rand, sizeof(id->rand));
> >+ key->bdaddr_type = addr_type;
> >+ memcpy(key->val, tk, sizeof(key->val));
> >+ key->authenticated = authenticated;
> >+ key->ediv = ediv;
> >+ key->enc_size = enc_size;
> >+ key->type = type;
> >+ memcpy(key->rand, rand, sizeof(key->rand));
> >
> >- if (new_key)
> >- mgmt_new_link_key(hdev, key, old_key_type);
> >+ if (!new_key)
> >+ return 0;
> >
> > return 0;
> > }
> >diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> >index 94a9ca2..750fc0c 100644
> >--- a/net/bluetooth/hci_event.c
> >+++ b/net/bluetooth/hci_event.c
> >@@ -3227,7 +3227,7 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
> > struct hci_cp_le_ltk_reply cp;
> > struct hci_cp_le_ltk_neg_reply neg;
> > struct hci_conn *conn;
> >- struct link_key *ltk;
> >+ struct smp_ltk *ltk;
> >
> > BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
> >
> >@@ -3243,10 +3243,15 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
> >
> > memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
> > cp.handle = cpu_to_le16(conn->handle);
> >- conn->pin_length = ltk->pin_len;
> >+
> >+ if (ltk->authenticated)
> >+ conn->sec_level = BT_SECURITY_HIGH;
> >
> > hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp),&cp);
> >
> >+ if (ltk->type& HCI_SMP_STK)
> >+ kfree(ltk);
> >+
> > hci_dev_unlock(hdev);
> >
> > return;
> >diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> >index b7f2fd1..7bc82e4 100644
> >--- a/net/bluetooth/smp.c
> >+++ b/net/bluetooth/smp.c
> >@@ -472,8 +472,9 @@ static void random_work(struct work_struct *work)
> > memset(stk + smp->enc_key_size, 0,
> > SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
> >
> >- hci_add_ltk(hcon->hdev, 0, conn->dst, smp->enc_key_size,
> >- ediv, rand, stk);
> >+ hci_add_ltk(hcon->hdev, conn->dst, hcon->dst_type,
> >+ HCI_SMP_STK_SLAVE, 0, 0, stk,
> >+ smp->enc_key_size, ediv, rand);
> > }
> >
> > return;
> >@@ -698,12 +699,10 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
> >
> > static u8 smp_ltk_encrypt(struct l2cap_conn *conn)
> > {
> >- struct link_key *key;
> >- struct key_master_id *master;
> >+ struct smp_ltk *key;
> > struct hci_conn *hcon = conn->hcon;
> >
> >- key = hci_find_link_key_type(hcon->hdev, conn->dst,
> >- HCI_LK_SMP_LTK);
> >+ key = hci_find_ltk_addr(hcon->hdev, conn->dst, hcon->dst_type);
> > if (!key)
> > return 0;
> >
> >@@ -711,10 +710,8 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn)
> > &hcon->pend))
> > return 1;
> >
> >- master = (void *) key->data;
> >- hci_le_start_enc(hcon, master->ediv, master->rand,
> >- key->val);
> >- hcon->enc_key_size = key->pin_len;
> >+ hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
> >+ hcon->enc_key_size = key->enc_size;
> >
> > return 1;
> >
> >@@ -817,13 +814,19 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
> > {
> > struct smp_cmd_master_ident *rp = (void *) skb->data;
> > struct smp_chan *smp = conn->smp_chan;
> >+ struct hci_dev *hdev = conn->hcon->hdev;
> >+ struct hci_conn *hcon = conn->hcon;
> >+ u8 authenticated;
> >
> > skb_pull(skb, sizeof(*rp));
> >
> >- hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->enc_key_size,
> >- rp->ediv, rp->rand, smp->tk);
> >-
> >+ hci_dev_lock(hdev);
> >+ authenticated = (conn->hcon->sec_level == BT_SECURITY_HIGH);
> >+ hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
> >+ HCI_SMP_LTK, 1, authenticated, smp->tk,
> >+ smp->enc_key_size, rp->ediv, rp->rand);
> > smp_distribute_keys(conn, 1);
> >+ hci_dev_unlock(hdev);
> >
> > return 0;
> > }
> >@@ -933,6 +936,8 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
> > if (*keydist& SMP_DIST_ENC_KEY) {
> > struct smp_cmd_encrypt_info enc;
> > struct smp_cmd_master_ident ident;
> >+ struct hci_conn *hcon = conn->hcon;
> >+ u8 authenticated;
> > __le16 ediv;
> >
> > get_random_bytes(enc.ltk, sizeof(enc.ltk));
> >@@ -941,8 +946,11 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
> >
> > smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc),&enc);
> >
> >- hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->enc_key_size,
> >- ediv, ident.rand, enc.ltk);
> >+ authenticated = hcon->sec_level == BT_SECURITY_HIGH;
> >+ hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
> >+ HCI_SMP_LTK_SLAVE, 1, authenticated,
> >+ enc.ltk, smp->enc_key_size,
> >+ ediv, ident.rand);
> >
> > ident.ediv = cpu_to_le16(ediv);
> >
>
>
> --
> Brian Gix
> bgix@codeaurora.org
> Employee of Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
--
Vinicius
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 1/8] Bluetooth: Add structures for the new LTK exchange messages
2012-01-13 20:40 ` Vinicius Costa Gomes
@ 2012-01-17 0:14 ` Vinicius Costa Gomes
0 siblings, 0 replies; 20+ messages in thread
From: Vinicius Costa Gomes @ 2012-01-17 0:14 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
This defines two new messages, one event that will inform
userspace that a new Long Term Key was exchanged and one that
will allow userspace to load LTKs into the kernel.
Besides the information necessary for the restablishement of
the secure link, we added some extra information: "authenticated"
that informs if the key can be used to establish an authenticated
link, and "master" that informs the role in that the key should
be used.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
include/net/bluetooth/mgmt.h | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index be65d34..c0bff97 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -288,6 +288,22 @@ struct mgmt_cp_unblock_device {
bdaddr_t bdaddr;
} __packed;
+struct mgmt_ltk_info {
+ struct mgmt_addr_info addr;
+ __u8 authenticated;
+ __u8 master;
+ __u8 enc_size;
+ __le16 ediv;
+ __u8 rand[8];
+ __u8 val[16];
+} __packed;
+
+#define MGMT_OP_LOAD_LONG_TERM_KEYS 0x0026
+struct mgmt_cp_load_long_term_keys {
+ __le16 key_count;
+ struct mgmt_ltk_info keys[0];
+} __packed;
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
@@ -388,3 +404,9 @@ struct mgmt_ev_device_blocked {
struct mgmt_ev_device_unblocked {
bdaddr_t bdaddr;
} __packed;
+
+#define MGMT_EV_NEW_LONG_TERM_KEY 0x0016
+struct mgmt_ev_new_long_term_key {
+ __u8 store_hint;
+ struct mgmt_ltk_info key;
+} __packed;
--
1.7.8.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 4/8] Bluetooth: Use the updated key structures for handling LTKs
2012-01-13 21:43 ` Vinicius Costa Gomes
@ 2012-01-17 0:17 ` Vinicius Costa Gomes
0 siblings, 0 replies; 20+ messages in thread
From: Vinicius Costa Gomes @ 2012-01-17 0:17 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
This updates all the users of the older way, that was using the
link_keys list to store the SMP keys, to use the new way.
This includes defining new types for the keys, we have a type for each
combination of STK/LTK and Master/Slave.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 11 +++--
net/bluetooth/hci_core.c | 79 ++++++++++++++++++--------------------
net/bluetooth/hci_event.c | 9 +++-
net/bluetooth/smp.c | 38 +++++++++++-------
4 files changed, 73 insertions(+), 64 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 2884509..3f93fd2 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -651,12 +651,13 @@ int hci_link_keys_clear(struct hci_dev *hdev);
struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
-struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
-struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
- bdaddr_t *bdaddr, u8 type);
-int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
- u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
+struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
+int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
+ int new_key, u8 authenticated, u8 tk[16],
+ u8 enc_size, u16 ediv, u8 rand[8]);
int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
+struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ u8 addr_type);
int hci_smp_ltks_clear(struct hci_dev *hdev);
int hci_remote_oob_data_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 3b5902d..69d07e1 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1222,41 +1222,40 @@ static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
return 0;
}
-struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
+/* If the returned key is a STK it should be free'd by the caller */
+struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
{
- struct link_key *k;
-
- list_for_each_entry(k, &hdev->link_keys, list) {
- struct key_master_id *id;
+ struct smp_ltk *k, *tmp;
- if (k->type != HCI_LK_SMP_LTK)
+ list_for_each_entry_safe(k, tmp, &hdev->ltks, list) {
+ if (k->ediv != ediv ||
+ memcmp(rand, k->rand, sizeof(k->rand)))
continue;
- if (k->dlen != sizeof(*id))
- continue;
+ /* The STK should only be used once, no need to keep it */
+ if (k->type & HCI_SMP_STK)
+ list_del(&k->list);
- id = (void *) &k->data;
- if (id->ediv == ediv &&
- (memcmp(rand, id->rand, sizeof(id->rand)) == 0))
- return k;
+ return k;
}
return NULL;
}
EXPORT_SYMBOL(hci_find_ltk);
-struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
- bdaddr_t *bdaddr, u8 type)
+struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ u8 addr_type)
{
- struct link_key *k;
+ struct smp_ltk *k;
- list_for_each_entry(k, &hdev->link_keys, list)
- if (k->type == type && bacmp(bdaddr, &k->bdaddr) == 0)
+ list_for_each_entry(k, &hdev->ltks, list)
+ if (addr_type == k->bdaddr_type &&
+ bacmp(bdaddr, &k->bdaddr) == 0)
return k;
return NULL;
}
-EXPORT_SYMBOL(hci_find_link_key_type);
+EXPORT_SYMBOL(hci_find_ltk_addr);
int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
@@ -1313,40 +1312,36 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
return 0;
}
-int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
- u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16])
+int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
+ int new_key, u8 authenticated, u8 tk[16],
+ u8 enc_size, u16 ediv, u8 rand[8])
{
- struct link_key *key, *old_key;
- struct key_master_id *id;
- u8 old_key_type;
+ struct smp_ltk *key, *old_key;
- BT_DBG("%s addr %s", hdev->name, batostr(bdaddr));
+ if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
+ return 0;
- old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK);
- if (old_key) {
+ old_key = hci_find_ltk_addr(hdev, bdaddr, addr_type);
+ if (old_key)
key = old_key;
- old_key_type = old_key->type;
- } else {
- key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC);
+ else {
+ key = kzalloc(sizeof(*key), GFP_ATOMIC);
if (!key)
return -ENOMEM;
- list_add(&key->list, &hdev->link_keys);
- old_key_type = 0xff;
+ list_add(&key->list, &hdev->ltks);
}
- key->dlen = sizeof(*id);
-
bacpy(&key->bdaddr, bdaddr);
- memcpy(key->val, ltk, sizeof(key->val));
- key->type = HCI_LK_SMP_LTK;
- key->pin_len = key_size;
-
- id = (void *) &key->data;
- id->ediv = ediv;
- memcpy(id->rand, rand, sizeof(id->rand));
+ key->bdaddr_type = addr_type;
+ memcpy(key->val, tk, sizeof(key->val));
+ key->authenticated = authenticated;
+ key->ediv = ediv;
+ key->enc_size = enc_size;
+ key->type = type;
+ memcpy(key->rand, rand, sizeof(key->rand));
- if (new_key)
- mgmt_new_link_key(hdev, key, old_key_type);
+ if (!new_key)
+ return 0;
return 0;
}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index c2fe964..7251e00 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3234,7 +3234,7 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
struct hci_cp_le_ltk_reply cp;
struct hci_cp_le_ltk_neg_reply neg;
struct hci_conn *conn;
- struct link_key *ltk;
+ struct smp_ltk *ltk;
BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
@@ -3250,10 +3250,15 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
cp.handle = cpu_to_le16(conn->handle);
- conn->pin_length = ltk->pin_len;
+
+ if (ltk->authenticated)
+ conn->sec_level = BT_SECURITY_HIGH;
hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
+ if (ltk->type & HCI_SMP_STK)
+ kfree(ltk);
+
hci_dev_unlock(hdev);
return;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index b7f2fd1..7bc82e4 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -472,8 +472,9 @@ static void random_work(struct work_struct *work)
memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
- hci_add_ltk(hcon->hdev, 0, conn->dst, smp->enc_key_size,
- ediv, rand, stk);
+ hci_add_ltk(hcon->hdev, conn->dst, hcon->dst_type,
+ HCI_SMP_STK_SLAVE, 0, 0, stk,
+ smp->enc_key_size, ediv, rand);
}
return;
@@ -698,12 +699,10 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
static u8 smp_ltk_encrypt(struct l2cap_conn *conn)
{
- struct link_key *key;
- struct key_master_id *master;
+ struct smp_ltk *key;
struct hci_conn *hcon = conn->hcon;
- key = hci_find_link_key_type(hcon->hdev, conn->dst,
- HCI_LK_SMP_LTK);
+ key = hci_find_ltk_addr(hcon->hdev, conn->dst, hcon->dst_type);
if (!key)
return 0;
@@ -711,10 +710,8 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn)
&hcon->pend))
return 1;
- master = (void *) key->data;
- hci_le_start_enc(hcon, master->ediv, master->rand,
- key->val);
- hcon->enc_key_size = key->pin_len;
+ hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
+ hcon->enc_key_size = key->enc_size;
return 1;
@@ -817,13 +814,19 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct smp_cmd_master_ident *rp = (void *) skb->data;
struct smp_chan *smp = conn->smp_chan;
+ struct hci_dev *hdev = conn->hcon->hdev;
+ struct hci_conn *hcon = conn->hcon;
+ u8 authenticated;
skb_pull(skb, sizeof(*rp));
- hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->enc_key_size,
- rp->ediv, rp->rand, smp->tk);
-
+ hci_dev_lock(hdev);
+ authenticated = (conn->hcon->sec_level == BT_SECURITY_HIGH);
+ hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
+ HCI_SMP_LTK, 1, authenticated, smp->tk,
+ smp->enc_key_size, rp->ediv, rp->rand);
smp_distribute_keys(conn, 1);
+ hci_dev_unlock(hdev);
return 0;
}
@@ -933,6 +936,8 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
if (*keydist & SMP_DIST_ENC_KEY) {
struct smp_cmd_encrypt_info enc;
struct smp_cmd_master_ident ident;
+ struct hci_conn *hcon = conn->hcon;
+ u8 authenticated;
__le16 ediv;
get_random_bytes(enc.ltk, sizeof(enc.ltk));
@@ -941,8 +946,11 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
- hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->enc_key_size,
- ediv, ident.rand, enc.ltk);
+ authenticated = hcon->sec_level == BT_SECURITY_HIGH;
+ hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
+ HCI_SMP_LTK_SLAVE, 1, authenticated,
+ enc.ltk, smp->enc_key_size,
+ ediv, ident.rand);
ident.ediv = cpu_to_le16(ediv);
--
1.7.8.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 4/8] Bluetooth: Use the updated key structures for handling LTKs
2012-01-30 22:29 [PATCH 0/8] [Resend] New MGMT messages for SMP Long Term Keys Vinicius Costa Gomes
@ 2012-01-30 22:29 ` Vinicius Costa Gomes
2012-01-30 22:44 ` Marcel Holtmann
0 siblings, 1 reply; 20+ messages in thread
From: Vinicius Costa Gomes @ 2012-01-30 22:29 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
This updates all the users of the older way, that was using the
link_keys list to store the SMP keys, to use the new way.
This includes defining new types for the keys, we have a type for each
combination of STK/LTK and Master/Slave.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 11 +++--
net/bluetooth/hci_core.c | 79 ++++++++++++++++++--------------------
net/bluetooth/hci_event.c | 9 +++-
net/bluetooth/smp.c | 38 +++++++++++-------
4 files changed, 73 insertions(+), 64 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 06eab3f..ae3f653 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -658,12 +658,13 @@ int hci_link_keys_clear(struct hci_dev *hdev);
struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
-struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
-struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
- bdaddr_t *bdaddr, u8 type);
-int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
- u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
+struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
+int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
+ int new_key, u8 authenticated, u8 tk[16],
+ u8 enc_size, u16 ediv, u8 rand[8]);
int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
+struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ u8 addr_type);
int hci_smp_ltks_clear(struct hci_dev *hdev);
int hci_remote_oob_data_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index a7b2d6b..d00704e 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1222,41 +1222,40 @@ static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
return 0;
}
-struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
+/* If the returned key is a STK it should be free'd by the caller */
+struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
{
- struct link_key *k;
-
- list_for_each_entry(k, &hdev->link_keys, list) {
- struct key_master_id *id;
+ struct smp_ltk *k, *tmp;
- if (k->type != HCI_LK_SMP_LTK)
+ list_for_each_entry_safe(k, tmp, &hdev->ltks, list) {
+ if (k->ediv != ediv ||
+ memcmp(rand, k->rand, sizeof(k->rand)))
continue;
- if (k->dlen != sizeof(*id))
- continue;
+ /* The STK should only be used once, no need to keep it */
+ if (k->type & HCI_SMP_STK)
+ list_del(&k->list);
- id = (void *) &k->data;
- if (id->ediv == ediv &&
- (memcmp(rand, id->rand, sizeof(id->rand)) == 0))
- return k;
+ return k;
}
return NULL;
}
EXPORT_SYMBOL(hci_find_ltk);
-struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
- bdaddr_t *bdaddr, u8 type)
+struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ u8 addr_type)
{
- struct link_key *k;
+ struct smp_ltk *k;
- list_for_each_entry(k, &hdev->link_keys, list)
- if (k->type == type && bacmp(bdaddr, &k->bdaddr) == 0)
+ list_for_each_entry(k, &hdev->ltks, list)
+ if (addr_type == k->bdaddr_type &&
+ bacmp(bdaddr, &k->bdaddr) == 0)
return k;
return NULL;
}
-EXPORT_SYMBOL(hci_find_link_key_type);
+EXPORT_SYMBOL(hci_find_ltk_addr);
int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
@@ -1313,40 +1312,36 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
return 0;
}
-int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
- u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16])
+int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
+ int new_key, u8 authenticated, u8 tk[16],
+ u8 enc_size, u16 ediv, u8 rand[8])
{
- struct link_key *key, *old_key;
- struct key_master_id *id;
- u8 old_key_type;
+ struct smp_ltk *key, *old_key;
- BT_DBG("%s addr %s", hdev->name, batostr(bdaddr));
+ if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
+ return 0;
- old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK);
- if (old_key) {
+ old_key = hci_find_ltk_addr(hdev, bdaddr, addr_type);
+ if (old_key)
key = old_key;
- old_key_type = old_key->type;
- } else {
- key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC);
+ else {
+ key = kzalloc(sizeof(*key), GFP_ATOMIC);
if (!key)
return -ENOMEM;
- list_add(&key->list, &hdev->link_keys);
- old_key_type = 0xff;
+ list_add(&key->list, &hdev->ltks);
}
- key->dlen = sizeof(*id);
-
bacpy(&key->bdaddr, bdaddr);
- memcpy(key->val, ltk, sizeof(key->val));
- key->type = HCI_LK_SMP_LTK;
- key->pin_len = key_size;
-
- id = (void *) &key->data;
- id->ediv = ediv;
- memcpy(id->rand, rand, sizeof(id->rand));
+ key->bdaddr_type = addr_type;
+ memcpy(key->val, tk, sizeof(key->val));
+ key->authenticated = authenticated;
+ key->ediv = ediv;
+ key->enc_size = enc_size;
+ key->type = type;
+ memcpy(key->rand, rand, sizeof(key->rand));
- if (new_key)
- mgmt_new_link_key(hdev, key, old_key_type);
+ if (!new_key)
+ return 0;
return 0;
}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 6fb9016..ea0b464 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3252,7 +3252,7 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
struct hci_cp_le_ltk_reply cp;
struct hci_cp_le_ltk_neg_reply neg;
struct hci_conn *conn;
- struct link_key *ltk;
+ struct smp_ltk *ltk;
BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
@@ -3268,10 +3268,15 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
cp.handle = cpu_to_le16(conn->handle);
- conn->pin_length = ltk->pin_len;
+
+ if (ltk->authenticated)
+ conn->sec_level = BT_SECURITY_HIGH;
hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
+ if (ltk->type & HCI_SMP_STK)
+ kfree(ltk);
+
hci_dev_unlock(hdev);
return;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 5818334..ad61905 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -472,8 +472,9 @@ static void random_work(struct work_struct *work)
memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
- hci_add_ltk(hcon->hdev, 0, conn->dst, smp->enc_key_size,
- ediv, rand, stk);
+ hci_add_ltk(hcon->hdev, conn->dst, hcon->dst_type,
+ HCI_SMP_STK_SLAVE, 0, 0, stk,
+ smp->enc_key_size, ediv, rand);
}
return;
@@ -698,22 +699,18 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
static u8 smp_ltk_encrypt(struct l2cap_conn *conn)
{
- struct link_key *key;
- struct key_master_id *master;
+ struct smp_ltk *key;
struct hci_conn *hcon = conn->hcon;
- key = hci_find_link_key_type(hcon->hdev, conn->dst,
- HCI_LK_SMP_LTK);
+ key = hci_find_ltk_addr(hcon->hdev, conn->dst, hcon->dst_type);
if (!key)
return 0;
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
return 1;
- master = (void *) key->data;
- hci_le_start_enc(hcon, master->ediv, master->rand,
- key->val);
- hcon->enc_key_size = key->pin_len;
+ hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
+ hcon->enc_key_size = key->enc_size;
return 1;
@@ -816,13 +813,19 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct smp_cmd_master_ident *rp = (void *) skb->data;
struct smp_chan *smp = conn->smp_chan;
+ struct hci_dev *hdev = conn->hcon->hdev;
+ struct hci_conn *hcon = conn->hcon;
+ u8 authenticated;
skb_pull(skb, sizeof(*rp));
- hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->enc_key_size,
- rp->ediv, rp->rand, smp->tk);
-
+ hci_dev_lock(hdev);
+ authenticated = (conn->hcon->sec_level == BT_SECURITY_HIGH);
+ hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
+ HCI_SMP_LTK, 1, authenticated, smp->tk,
+ smp->enc_key_size, rp->ediv, rp->rand);
smp_distribute_keys(conn, 1);
+ hci_dev_unlock(hdev);
return 0;
}
@@ -932,6 +935,8 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
if (*keydist & SMP_DIST_ENC_KEY) {
struct smp_cmd_encrypt_info enc;
struct smp_cmd_master_ident ident;
+ struct hci_conn *hcon = conn->hcon;
+ u8 authenticated;
__le16 ediv;
get_random_bytes(enc.ltk, sizeof(enc.ltk));
@@ -940,8 +945,11 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
- hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->enc_key_size,
- ediv, ident.rand, enc.ltk);
+ authenticated = hcon->sec_level == BT_SECURITY_HIGH;
+ hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
+ HCI_SMP_LTK_SLAVE, 1, authenticated,
+ enc.ltk, smp->enc_key_size,
+ ediv, ident.rand);
ident.ediv = cpu_to_le16(ediv);
--
1.7.8.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 4/8] Bluetooth: Use the updated key structures for handling LTKs
2012-01-30 22:29 ` [PATCH 4/8] Bluetooth: Use the updated key structures for handling LTKs Vinicius Costa Gomes
@ 2012-01-30 22:44 ` Marcel Holtmann
2012-01-30 23:24 ` Vinicius Costa Gomes
0 siblings, 1 reply; 20+ messages in thread
From: Marcel Holtmann @ 2012-01-30 22:44 UTC (permalink / raw)
To: Vinicius Costa Gomes; +Cc: linux-bluetooth
Hi Vinicius,
> This updates all the users of the older way, that was using the
> link_keys list to store the SMP keys, to use the new way.
>
> This includes defining new types for the keys, we have a type for each
> combination of STK/LTK and Master/Slave.
>
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> ---
> include/net/bluetooth/hci_core.h | 11 +++--
> net/bluetooth/hci_core.c | 79 ++++++++++++++++++--------------------
> net/bluetooth/hci_event.c | 9 +++-
> net/bluetooth/smp.c | 38 +++++++++++-------
> 4 files changed, 73 insertions(+), 64 deletions(-)
>
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index 06eab3f..ae3f653 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -658,12 +658,13 @@ int hci_link_keys_clear(struct hci_dev *hdev);
> struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
> int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
> bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
> -struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
> -struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
> - bdaddr_t *bdaddr, u8 type);
> -int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
> - u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
> +struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
> +int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
> + int new_key, u8 authenticated, u8 tk[16],
> + u8 enc_size, u16 ediv, u8 rand[8]);
> int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
> +struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
> + u8 addr_type);
> int hci_smp_ltks_clear(struct hci_dev *hdev);
>
> int hci_remote_oob_data_clear(struct hci_dev *hdev);
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index a7b2d6b..d00704e 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -1222,41 +1222,40 @@ static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
> return 0;
> }
>
> -struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
> +/* If the returned key is a STK it should be free'd by the caller */
> +struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
> {
this kind of API seems to be rather random. We need a bit better
semantics here.
Regards
Marcel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 4/8] Bluetooth: Use the updated key structures for handling LTKs
2012-01-30 22:44 ` Marcel Holtmann
@ 2012-01-30 23:24 ` Vinicius Costa Gomes
2012-01-31 0:48 ` Marcel Holtmann
0 siblings, 1 reply; 20+ messages in thread
From: Vinicius Costa Gomes @ 2012-01-30 23:24 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
Hi Marcel,
On 14:44 Mon 30 Jan, Marcel Holtmann wrote:
> Hi Vinicius,
>
> > This updates all the users of the older way, that was using the
> > link_keys list to store the SMP keys, to use the new way.
> >
> > This includes defining new types for the keys, we have a type for each
> > combination of STK/LTK and Master/Slave.
> >
> > Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> > ---
> > include/net/bluetooth/hci_core.h | 11 +++--
> > net/bluetooth/hci_core.c | 79 ++++++++++++++++++--------------------
> > net/bluetooth/hci_event.c | 9 +++-
> > net/bluetooth/smp.c | 38 +++++++++++-------
> > 4 files changed, 73 insertions(+), 64 deletions(-)
> >
> > diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> > index 06eab3f..ae3f653 100644
> > --- a/include/net/bluetooth/hci_core.h
> > +++ b/include/net/bluetooth/hci_core.h
> > @@ -658,12 +658,13 @@ int hci_link_keys_clear(struct hci_dev *hdev);
> > struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
> > int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
> > bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
> > -struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
> > -struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
> > - bdaddr_t *bdaddr, u8 type);
> > -int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
> > - u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
> > +struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
> > +int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
> > + int new_key, u8 authenticated, u8 tk[16],
> > + u8 enc_size, u16 ediv, u8 rand[8]);
> > int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
> > +struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
> > + u8 addr_type);
> > int hci_smp_ltks_clear(struct hci_dev *hdev);
> >
> > int hci_remote_oob_data_clear(struct hci_dev *hdev);
> > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> > index a7b2d6b..d00704e 100644
> > --- a/net/bluetooth/hci_core.c
> > +++ b/net/bluetooth/hci_core.c
> > @@ -1222,41 +1222,40 @@ static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
> > return 0;
> > }
> >
> > -struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
> > +/* If the returned key is a STK it should be free'd by the caller */
> > +struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
> > {
>
> this kind of API seems to be rather random. We need a bit better
> semantics here.
Ok. I can leave the work of removing the STK from the list to the
caller. Would that make more sense to you?
The point is that it doesn't make sense to keep the STK around after
it was used.
>
> Regards
>
> Marcel
>
>
Cheers,
--
Vinicius
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 4/8] Bluetooth: Use the updated key structures for handling LTKs
2012-01-30 23:24 ` Vinicius Costa Gomes
@ 2012-01-31 0:48 ` Marcel Holtmann
0 siblings, 0 replies; 20+ messages in thread
From: Marcel Holtmann @ 2012-01-31 0:48 UTC (permalink / raw)
To: Vinicius Costa Gomes; +Cc: linux-bluetooth
Hi Vinicius,
> > > This updates all the users of the older way, that was using the
> > > link_keys list to store the SMP keys, to use the new way.
> > >
> > > This includes defining new types for the keys, we have a type for each
> > > combination of STK/LTK and Master/Slave.
> > >
> > > Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> > > ---
> > > include/net/bluetooth/hci_core.h | 11 +++--
> > > net/bluetooth/hci_core.c | 79 ++++++++++++++++++--------------------
> > > net/bluetooth/hci_event.c | 9 +++-
> > > net/bluetooth/smp.c | 38 +++++++++++-------
> > > 4 files changed, 73 insertions(+), 64 deletions(-)
> > >
> > > diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> > > index 06eab3f..ae3f653 100644
> > > --- a/include/net/bluetooth/hci_core.h
> > > +++ b/include/net/bluetooth/hci_core.h
> > > @@ -658,12 +658,13 @@ int hci_link_keys_clear(struct hci_dev *hdev);
> > > struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
> > > int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
> > > bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
> > > -struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
> > > -struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
> > > - bdaddr_t *bdaddr, u8 type);
> > > -int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
> > > - u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
> > > +struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
> > > +int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
> > > + int new_key, u8 authenticated, u8 tk[16],
> > > + u8 enc_size, u16 ediv, u8 rand[8]);
> > > int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
> > > +struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
> > > + u8 addr_type);
> > > int hci_smp_ltks_clear(struct hci_dev *hdev);
> > >
> > > int hci_remote_oob_data_clear(struct hci_dev *hdev);
> > > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> > > index a7b2d6b..d00704e 100644
> > > --- a/net/bluetooth/hci_core.c
> > > +++ b/net/bluetooth/hci_core.c
> > > @@ -1222,41 +1222,40 @@ static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
> > > return 0;
> > > }
> > >
> > > -struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
> > > +/* If the returned key is a STK it should be free'd by the caller */
> > > +struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
> > > {
> >
> > this kind of API seems to be rather random. We need a bit better
> > semantics here.
>
> Ok. I can leave the work of removing the STK from the list to the
> caller. Would that make more sense to you?
>
> The point is that it doesn't make sense to keep the STK around after
> it was used.
that would be better. Then at least the semantics are clear.
Regards
Marcel
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2012-01-31 0:48 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-13 19:39 [PATCH 0/8] New MGMT messages for SMP Long Term Keys Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 1/8] Bluetooth: Add structures for the new LTK exchange messages Vinicius Costa Gomes
2012-01-13 20:37 ` Brian Gix
2012-01-13 20:40 ` Vinicius Costa Gomes
2012-01-17 0:14 ` Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 2/8] Bluetooth: Rename smp_key_size to enc_key_size Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 3/8] Bluetooth: Add new structures for handling SMP Long Term Keys Vinicius Costa Gomes
2012-01-13 20:43 ` Brian Gix
2012-01-13 19:39 ` [PATCH 4/8] Bluetooth: Use the updated key structures for handling LTKs Vinicius Costa Gomes
2012-01-13 20:52 ` Brian Gix
2012-01-13 21:43 ` Vinicius Costa Gomes
2012-01-17 0:17 ` Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 5/8] Bluetooth: Add MGMT handlers for dealing with SMP LTK's Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 6/8] Bluetooth: Add support for removing LTK's when pairing is removed Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 7/8] Bluetooth: Clean up structures left unused Vinicius Costa Gomes
2012-01-13 19:39 ` [PATCH 8/8] Bluetooth: Add support for notifying userspace of new LTK's Vinicius Costa Gomes
-- strict thread matches above, loose matches on Subject: below --
2012-01-30 22:29 [PATCH 0/8] [Resend] New MGMT messages for SMP Long Term Keys Vinicius Costa Gomes
2012-01-30 22:29 ` [PATCH 4/8] Bluetooth: Use the updated key structures for handling LTKs Vinicius Costa Gomes
2012-01-30 22:44 ` Marcel Holtmann
2012-01-30 23:24 ` Vinicius Costa Gomes
2012-01-31 0:48 ` Marcel Holtmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).