Linux bluetooth development
 help / color / mirror / Atom feed
From: johan.hedberg@gmail.com
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH v2 10/10] Bluetooth: Wait for SMP key distribution completion when pairing
Date: Tue, 18 Feb 2014 17:44:45 +0200	[thread overview]
Message-ID: <1392738285-12143-1-git-send-email-johan.hedberg@gmail.com> (raw)
In-Reply-To: <1392736479-8808-11-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

When we initiate pairing through mgmt_pair_device the code has so far
been waiting for a successful HCI Encrypt Change event in order to
respond to the mgmt command. However, putting privacy into the play we
actually want the key distribution to be complete before replying so
that we can include the Identity Address in the mgmt response.

This patch updates the various hci_conn callbacks for LE in mgmt.c to
only respond in the case of failure, and adds a new mgmt_smp_complete
function that the SMP code will call once key distribution has been
completed.

Since the smp_chan_destroy function that's used to indicate completion
and clean up the SMP context can be called from various places,
including outside of smp.c, the easiest way to track failure vs success
is a new flag that we set once key distribution has been successfully
completed.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
v2: Fix passing correct status value to pairing_complete()

 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/mgmt.c             | 27 +++++++++++++++++++++------
 net/bluetooth/smp.c              |  5 +++++
 net/bluetooth/smp.h              |  1 +
 4 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 4461c0051228..64c4e3f0a515 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1212,6 +1212,7 @@ int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
 int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
 void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent);
 void mgmt_reenable_advertising(struct hci_dev *hdev);
+void mgmt_smp_complete(struct hci_conn *conn, bool complete);
 
 /* 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 90aac905a98b..f9ae72ca556d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2655,6 +2655,18 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status)
 	mgmt_pending_remove(cmd);
 }
 
+void mgmt_smp_complete(struct hci_conn *conn, bool complete)
+{
+	u8 status = complete ? MGMT_STATUS_SUCCESS : MGMT_STATUS_FAILED;
+	struct pending_cmd *cmd;
+
+	cmd = find_pairing(conn);
+	if (!cmd)
+		BT_DBG("Unable to find a pending command");
+	else
+		pairing_complete(cmd, status);
+}
+
 static void pairing_complete_cb(struct hci_conn *conn, u8 status)
 {
 	struct pending_cmd *cmd;
@@ -2668,7 +2680,7 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status)
 		pairing_complete(cmd, mgmt_status(status));
 }
 
-static void le_connect_complete_cb(struct hci_conn *conn, u8 status)
+static void le_pairing_complete_cb(struct hci_conn *conn, u8 status)
 {
 	struct pending_cmd *cmd;
 
@@ -2755,13 +2767,16 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
 	}
 
 	/* For LE, just connecting isn't a proof that the pairing finished */
-	if (cp->addr.type == BDADDR_BREDR)
+	if (cp->addr.type == BDADDR_BREDR) {
 		conn->connect_cfm_cb = pairing_complete_cb;
-	else
-		conn->connect_cfm_cb = le_connect_complete_cb;
+		conn->security_cfm_cb = pairing_complete_cb;
+		conn->disconn_cfm_cb = pairing_complete_cb;
+	} else {
+		conn->connect_cfm_cb = le_pairing_complete_cb;
+		conn->security_cfm_cb = le_pairing_complete_cb;
+		conn->disconn_cfm_cb = le_pairing_complete_cb;
+	}
 
-	conn->security_cfm_cb = pairing_complete_cb;
-	conn->disconn_cfm_cb = pairing_complete_cb;
 	conn->io_capability = cp->io_cap;
 	cmd->user_data = conn;
 
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index faf04bd4263a..9741623de6e7 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -551,9 +551,13 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
 void smp_chan_destroy(struct l2cap_conn *conn)
 {
 	struct smp_chan *smp = conn->smp_chan;
+	bool complete;
 
 	BUG_ON(!smp);
 
+	complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
+	mgmt_smp_complete(conn->hcon, complete);
+
 	kfree(smp);
 	conn->smp_chan = NULL;
 	conn->hcon->smp_conn = NULL;
@@ -1172,6 +1176,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
 	if (conn->hcon->out || force || !(rsp->init_key_dist & 0x07)) {
 		clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
 		cancel_delayed_work_sync(&conn->security_timer);
+		set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
 		smp_chan_destroy(conn);
 	}
 
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
index 8f54c9b152de..675fd3b21d2c 100644
--- a/net/bluetooth/smp.h
+++ b/net/bluetooth/smp.h
@@ -118,6 +118,7 @@ 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
 
 struct smp_chan {
 	struct l2cap_conn *conn;
-- 
1.8.5.3


  reply	other threads:[~2014-02-18 15:44 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-18 15:14 [PATCH 00/10] Bluetooth: More patches for privacy johan.hedberg
2014-02-18 15:14 ` [PATCH 01/10] Bluetooth: Remove SMP data specific crypto context johan.hedberg
2014-02-18 16:04   ` Marcel Holtmann
2014-02-18 16:24     ` Johan Hedberg
2014-02-18 16:29       ` Johan Hedberg
2014-02-18 17:34         ` Marcel Holtmann
2014-02-18 15:14 ` [PATCH 02/10] Bluetooth: Fix missing address type check for removing LTKs johan.hedberg
2014-02-18 15:14 ` [PATCH 03/10] Bluetooth: Remove return values from functions that don't need them johan.hedberg
2014-02-18 15:14 ` [PATCH 04/10] Bluetooth: Fix hci_remove_ltk failure when no match is found johan.hedberg
2014-02-18 15:14 ` [PATCH 05/10] Bluetooth: Fix completing SMP as peripheral when no keys are expected johan.hedberg
2014-02-18 15:14 ` [PATCH 06/10] Bluetooth: Fix removing any IRKs when unpairing devices johan.hedberg
2014-02-18 15:14 ` [PATCH 07/10] Bluetooth: Add convenience function for fetching IRKs johan.hedberg
2014-02-18 15:14 ` [PATCH 08/10] Bluetooth: Track the LE Identity Address in struct hci_conn johan.hedberg
2014-02-18 17:01   ` Marcel Holtmann
2014-02-18 15:14 ` [PATCH 09/10] Bluetooth: Fix updating Identity Address in L2CAP channels johan.hedberg
2014-02-18 18:25   ` Marcel Holtmann
2014-02-18 15:14 ` [PATCH 10/10] Bluetooth: Wait for SMP key distribution completion when pairing johan.hedberg
2014-02-18 15:44   ` johan.hedberg [this message]
2014-02-18 18:28     ` [PATCH v2 " Marcel Holtmann
2014-02-18 19:48       ` Johan Hedberg
2014-02-18 16:59 ` [PATCH 00/10] Bluetooth: More patches for privacy Marcel Holtmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1392738285-12143-1-git-send-email-johan.hedberg@gmail.com \
    --to=johan.hedberg@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox