* [PATCH 2/5] Bluetooth: Simplify logic for checking for SMP completion
2014-02-26 21:33 [PATCH 1/5] Bluetooth: Track not yet received keys in SMP johan.hedberg
@ 2014-02-26 21:33 ` johan.hedberg
2014-02-26 21:33 ` [PATCH 3/5] Bluetooth: Remove unneeded "force" parameter from smp_distribute_keys() johan.hedberg
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: johan.hedberg @ 2014-02-26 21:33 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
Now that smp->remote_key_dist is tracking the keys we're still waiting
for we can use it to simplify the logic for checking whether we're done
with key distribution or not. At the same time the reliance on the
"force" parameter of smp_distribute_keys goes away and it can completely
be removed in a subsequent patch.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/smp.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index fe41df5c320c..1b17adfffef8 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1184,7 +1184,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
rsp = (void *) &smp->prsp[1];
/* The responder sends its keys first */
- if (!force && hcon->out && (rsp->resp_key_dist & 0x07))
+ if (hcon->out && (smp->remote_key_dist & 0x07))
return 0;
req = (void *) &smp->preq[1];
@@ -1259,13 +1259,16 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
*keydist &= ~SMP_DIST_SIGN;
}
- if (hcon->out || force || !(rsp->init_key_dist & 0x07)) {
- clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
- cancel_delayed_work_sync(&conn->security_timer);
- set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
- smp_notify_keys(conn);
- smp_chan_destroy(conn);
- }
+ /* If there are still keys to be received wait for them */
+ if ((smp->remote_key_dist & 0x07))
+ return 0;
+
+ clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
+ cancel_delayed_work_sync(&conn->security_timer);
+ set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
+ smp_notify_keys(conn);
+
+ smp_chan_destroy(conn);
return 0;
}
--
1.8.5.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 3/5] Bluetooth: Remove unneeded "force" parameter from smp_distribute_keys()
2014-02-26 21:33 [PATCH 1/5] Bluetooth: Track not yet received keys in SMP johan.hedberg
2014-02-26 21:33 ` [PATCH 2/5] Bluetooth: Simplify logic for checking for SMP completion johan.hedberg
@ 2014-02-26 21:33 ` johan.hedberg
2014-02-26 21:47 ` Marcel Holtmann
2014-02-26 21:33 ` [PATCH 4/5] Bluetooth: Re-encrypt link after receiving an LTK johan.hedberg
2014-02-26 21:33 ` [PATCH 5/5] Bluetooth: Fix disconnecting connections in non-connected states johan.hedberg
3 siblings, 1 reply; 6+ messages in thread
From: johan.hedberg @ 2014-02-26 21:33 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
Now that to-be-received keys are properly tracked we no-longer need the
"force" parameter to smp_distribute_keys(). It was essentially acting as
an indicator whether all keys have been received, but now it's just
redundant together with smp->remote_key_dist.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/l2cap_core.c | 2 +-
net/bluetooth/smp.c | 10 +++++-----
net/bluetooth/smp.h | 2 +-
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 7bd78c5487fb..d8d990215158 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -7267,7 +7267,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
if (hcon->type == LE_LINK) {
if (!status && encrypt)
- smp_distribute_keys(conn, 0);
+ smp_distribute_keys(conn);
cancel_delayed_work(&conn->security_timer);
}
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 1b17adfffef8..0de98fe23330 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -960,7 +960,7 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
rp->ediv, rp->rand);
smp->ltk = ltk;
if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
- smp_distribute_keys(conn, 1);
+ smp_distribute_keys(conn);
hci_dev_unlock(hdev);
return 0;
@@ -1018,7 +1018,7 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
*/
if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
BT_ERR("Ignoring IRK with no identity address");
- smp_distribute_keys(conn, 1);
+ smp_distribute_keys(conn);
return 0;
}
@@ -1039,7 +1039,7 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
l2cap_conn_update_id_addr(hcon);
- smp_distribute_keys(conn, 1);
+ smp_distribute_keys(conn);
return 0;
}
@@ -1168,7 +1168,7 @@ static void smp_notify_keys(struct l2cap_conn *conn)
}
}
-int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
+int smp_distribute_keys(struct l2cap_conn *conn)
{
struct smp_cmd_pairing *req, *rsp;
struct smp_chan *smp = conn->smp_chan;
@@ -1176,7 +1176,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
struct hci_dev *hdev = hcon->hdev;
__u8 *keydist;
- BT_DBG("conn %p force %d", conn, force);
+ BT_DBG("conn %p", conn);
if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
return 0;
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
index f32f1212f650..1b8af35b292c 100644
--- a/net/bluetooth/smp.h
+++ b/net/bluetooth/smp.h
@@ -145,7 +145,7 @@ struct smp_chan {
bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level);
int smp_conn_security(struct hci_conn *hcon, __u8 sec_level);
int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);
-int smp_distribute_keys(struct l2cap_conn *conn, __u8 force);
+int smp_distribute_keys(struct l2cap_conn *conn);
int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey);
void smp_chan_destroy(struct l2cap_conn *conn);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 4/5] Bluetooth: Re-encrypt link after receiving an LTK
2014-02-26 21:33 [PATCH 1/5] Bluetooth: Track not yet received keys in SMP johan.hedberg
2014-02-26 21:33 ` [PATCH 2/5] Bluetooth: Simplify logic for checking for SMP completion johan.hedberg
2014-02-26 21:33 ` [PATCH 3/5] Bluetooth: Remove unneeded "force" parameter from smp_distribute_keys() johan.hedberg
@ 2014-02-26 21:33 ` johan.hedberg
2014-02-26 21:33 ` [PATCH 5/5] Bluetooth: Fix disconnecting connections in non-connected states johan.hedberg
3 siblings, 0 replies; 6+ messages in thread
From: johan.hedberg @ 2014-02-26 21:33 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
It's not strictly speaking required to re-encrypt a link once we receive
an LTK since the connection is already encrypted with the STK. However,
re-encrypting with the LTK allows us to verify that we've received an
LTK that actually works.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/smp.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 0de98fe23330..52708f79545f 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1268,6 +1268,13 @@ int smp_distribute_keys(struct l2cap_conn *conn)
set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
smp_notify_keys(conn);
+ /* Re-encrypt the link with LTK */
+ if (smp->ltk) {
+ struct smp_ltk *ltk = smp->ltk;
+ hci_le_start_enc(hcon, ltk->ediv, ltk->rand, ltk->val);
+ hcon->enc_key_size = ltk->enc_size;
+ }
+
smp_chan_destroy(conn);
return 0;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 5/5] Bluetooth: Fix disconnecting connections in non-connected states
2014-02-26 21:33 [PATCH 1/5] Bluetooth: Track not yet received keys in SMP johan.hedberg
` (2 preceding siblings ...)
2014-02-26 21:33 ` [PATCH 4/5] Bluetooth: Re-encrypt link after receiving an LTK johan.hedberg
@ 2014-02-26 21:33 ` johan.hedberg
3 siblings, 0 replies; 6+ messages in thread
From: johan.hedberg @ 2014-02-26 21:33 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
When powering off and disconnecting devices we should also consider
connections which have not yet reached the BT_CONNECTED state. They may
not have a valid handle yet and simply sending a HCI_Disconnect will not
work.
This patch updates the code to either disconnect, cancel connection
creation or reject incoming connection creation based on the current
conn->state value as well as the link type in question.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/mgmt.c | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index d6e269287cfc..d09e84fb7c3f 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1061,10 +1061,34 @@ static int clean_up_hci_state(struct hci_dev *hdev)
list_for_each_entry(conn, &hdev->conn_hash.list, list) {
struct hci_cp_disconnect dc;
-
- dc.handle = cpu_to_le16(conn->handle);
- dc.reason = 0x15; /* Terminated due to Power Off */
- hci_req_add(&req, HCI_OP_DISCONNECT, sizeof(dc), &dc);
+ struct hci_cp_reject_conn_req rej;
+
+ switch (conn->state) {
+ case BT_CONNECTED:
+ case BT_CONFIG:
+ dc.handle = cpu_to_le16(conn->handle);
+ dc.reason = 0x15; /* Terminated due to Power Off */
+ hci_req_add(&req, HCI_OP_DISCONNECT, sizeof(dc), &dc);
+ break;
+ case BT_CONNECT:
+ if (conn->type == LE_LINK)
+ hci_req_add(&req, HCI_OP_LE_CREATE_CONN_CANCEL,
+ 0, NULL);
+ else if (conn->type == ACL_LINK)
+ hci_req_add(&req, HCI_OP_CREATE_CONN_CANCEL,
+ 6, &conn->dst);
+ break;
+ case BT_CONNECT2:
+ bacpy(&rej.bdaddr, &conn->dst);
+ rej.reason = 0x15; /* Terminated due to Power Off */
+ if (conn->type == ACL_LINK)
+ hci_req_add(&req, HCI_OP_REJECT_CONN_REQ,
+ sizeof(rej), &rej);
+ else if (conn->type == SCO_LINK)
+ hci_req_add(&req, HCI_OP_REJECT_SYNC_CONN_REQ,
+ sizeof(rej), &rej);
+ break;
+ }
}
return hci_req_run(&req, clean_up_hci_complete);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 6+ messages in thread