* [PATCH v2 1/2] Bluetooth: Re-encrypt link after receiving an LTK @ 2014-02-27 12:35 johan.hedberg 2014-02-27 12:35 ` [PATCH v2 2/2] Bluetooth: Fix disconnecting connections in non-connected states johan.hedberg 0 siblings, 1 reply; 3+ messages in thread From: johan.hedberg @ 2014-02-27 12:35 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. This patch updates the SMP code to request encrypting with the LTK in case we're in master role and waits until the key refresh complete event before notifying user space of the distributed keys. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> --- net/bluetooth/smp.c | 23 ++++++++++++++++++----- net/bluetooth/smp.h | 3 ++- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 0de98fe23330..f586728f6694 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1174,6 +1174,7 @@ int smp_distribute_keys(struct l2cap_conn *conn) struct smp_chan *smp = conn->smp_chan; struct hci_conn *hcon = conn->hcon; struct hci_dev *hdev = hcon->hdev; + bool ltk_encrypt; __u8 *keydist; BT_DBG("conn %p", conn); @@ -1263,12 +1264,24 @@ int smp_distribute_keys(struct l2cap_conn *conn) 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); + if (smp->ltk) + ltk_encrypt = !test_and_set_bit(SMP_FLAG_LTK_ENCRYPT, + &smp->smp_flags); + else + ltk_encrypt = false; - smp_chan_destroy(conn); + /* Re-encrypt the link with LTK if possible */ + if (ltk_encrypt && hcon->out) { + struct smp_ltk *ltk = smp->ltk; + hci_le_start_enc(hcon, ltk->ediv, ltk->rand, ltk->val); + hcon->enc_key_size = ltk->enc_size; + } else { + 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; } diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index 1b8af35b292c..e079e8441682 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h @@ -118,7 +118,8 @@ struct smp_cmd_security_req { #define SMP_FLAG_TK_VALID 1 #define SMP_FLAG_CFM_PENDING 2 #define SMP_FLAG_MITM_AUTH 3 -#define SMP_FLAG_COMPLETE 4 +#define SMP_FLAG_LTK_ENCRYPT 4 +#define SMP_FLAG_COMPLETE 5 struct smp_chan { struct l2cap_conn *conn; -- 1.8.5.3 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v2 2/2] Bluetooth: Fix disconnecting connections in non-connected states 2014-02-27 12:35 [PATCH v2 1/2] Bluetooth: Re-encrypt link after receiving an LTK johan.hedberg @ 2014-02-27 12:35 ` johan.hedberg 2014-02-28 7:35 ` Marcel Holtmann 0 siblings, 1 reply; 3+ messages in thread From: johan.hedberg @ 2014-02-27 12:35 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. When the power off procedure results in canceling connection attempts instead of disconnecting connections we get a connection failed event instead of a disconnection event. Therefore, we also need to have extra code in the mgmt_connect_failed function to check if we should proceed with the power off or not. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> --- net/bluetooth/mgmt.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 4c4912e9a7c4..1e9747b60657 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1057,10 +1057,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); @@ -5182,6 +5206,18 @@ void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 status) { struct mgmt_ev_connect_failed ev; + struct pending_cmd *power_off; + + power_off = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); + if (power_off) { + struct mgmt_mode *cp = power_off->param; + + /* The connection is still in hci_conn_hash so test for 1 + * instead of 0 to know if this is the last one. + */ + if (!cp->val && hci_conn_count(hdev) == 1) + queue_work(hdev->req_workqueue, &hdev->power_off.work); + } bacpy(&ev.addr.bdaddr, bdaddr); ev.addr.type = link_to_bdaddr(link_type, addr_type); -- 1.8.5.3 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v2 2/2] Bluetooth: Fix disconnecting connections in non-connected states 2014-02-27 12:35 ` [PATCH v2 2/2] Bluetooth: Fix disconnecting connections in non-connected states johan.hedberg @ 2014-02-28 7:35 ` Marcel Holtmann 0 siblings, 0 replies; 3+ messages in thread From: Marcel Holtmann @ 2014-02-28 7:35 UTC (permalink / raw) To: Johan Hedberg; +Cc: linux-bluetooth Hi Johan, > 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. > > When the power off procedure results in canceling connection attempts > instead of disconnecting connections we get a connection failed event > instead of a disconnection event. Therefore, we also need to have extra > code in the mgmt_connect_failed function to check if we should proceed > with the power off or not. > > Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> > --- > net/bluetooth/mgmt.c | 44 ++++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 40 insertions(+), 4 deletions(-) patch has been applied to bluetooth-next tree. Regards Marcel ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-02-28 7:35 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-02-27 12:35 [PATCH v2 1/2] Bluetooth: Re-encrypt link after receiving an LTK johan.hedberg 2014-02-27 12:35 ` [PATCH v2 2/2] Bluetooth: Fix disconnecting connections in non-connected states johan.hedberg 2014-02-28 7:35 ` Marcel Holtmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox