All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] Bluetooth: Re-encrypt link after receiving an LTK
@ 2014-02-28 14:37 johan.hedberg
  2014-02-28 14:37 ` [PATCH 2/2] Bluetooth: Delay LTK encryption to let remote receive all keys johan.hedberg
  0 siblings, 1 reply; 2+ messages in thread
From: johan.hedberg @ 2014-02-28 14:37 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.

A new flag is also added for the SMP context to ensure that we
re-encryption only once in case of multiple calls to smp_distribute_keys.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/smp.c | 27 ++++++++++++++++++++++-----
 net/bluetooth/smp.h |  3 ++-
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 4f4ff36f5f34..79b6c97f8303 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1178,6 +1178,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);
@@ -1269,12 +1270,28 @@ 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);
+	/* Check if we should try to re-encrypt the link with the LTK.
+	 * SMP_FLAG_LTK_ENCRYPT flag is used to track whether we've
+	 * already tried this (in which case we shouldn't try again).
+	 */
+	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 a11d4281542c..676395f93702 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] 2+ messages in thread

* [PATCH 2/2] Bluetooth: Delay LTK encryption to let remote receive all keys
  2014-02-28 14:37 [PATCH 1/2] Bluetooth: Re-encrypt link after receiving an LTK johan.hedberg
@ 2014-02-28 14:37 ` johan.hedberg
  0 siblings, 0 replies; 2+ messages in thread
From: johan.hedberg @ 2014-02-28 14:37 UTC (permalink / raw)
  To: linux-bluetooth

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

Some devices may refuse to re-encrypt with the LTK if they haven't
received all our keys yet. This patch adds a 200ms delay before
attempting re-encryption with the LTK.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/smp.c | 22 +++++++++++++++++++---
 net/bluetooth/smp.h |  3 +++
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 79b6c97f8303..cba0e0ddf332 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -549,6 +549,20 @@ error:
 	smp_failure(conn, reason);
 }
 
+static void smp_reencrypt(struct work_struct *work)
+{
+	struct smp_chan *smp = container_of(work, struct smp_chan,
+					    reencrypt.work);
+	struct l2cap_conn *conn = smp->conn;
+	struct hci_conn *hcon = conn->hcon;
+	struct smp_ltk *ltk = smp->ltk;
+
+	BT_DBG("");
+
+	hci_le_start_enc(hcon, ltk->ediv, ltk->rand, ltk->val);
+	hcon->enc_key_size = ltk->enc_size;
+}
+
 static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
 {
 	struct smp_chan *smp;
@@ -559,6 +573,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
 
 	INIT_WORK(&smp->confirm, confirm_work);
 	INIT_WORK(&smp->random, random_work);
+	INIT_DELAYED_WORK(&smp->reencrypt, smp_reencrypt);
 
 	smp->conn = conn;
 	conn->smp_chan = smp;
@@ -576,6 +591,8 @@ void smp_chan_destroy(struct l2cap_conn *conn)
 
 	BUG_ON(!smp);
 
+	cancel_delayed_work_sync(&smp->reencrypt);
+
 	complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
 	mgmt_smp_complete(conn->hcon, complete);
 
@@ -1282,9 +1299,8 @@ int smp_distribute_keys(struct l2cap_conn *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;
+		queue_delayed_work(hdev->req_workqueue, &smp->reencrypt,
+				   SMP_REENCRYPT_TIMEOUT);
 	} else {
 		clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
 		cancel_delayed_work_sync(&conn->security_timer);
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
index 676395f93702..f95bf887a9f3 100644
--- a/net/bluetooth/smp.h
+++ b/net/bluetooth/smp.h
@@ -121,6 +121,8 @@ struct smp_cmd_security_req {
 #define SMP_FLAG_LTK_ENCRYPT	4
 #define SMP_FLAG_COMPLETE	5
 
+#define SMP_REENCRYPT_TIMEOUT	msecs_to_jiffies(200)
+
 struct smp_chan {
 	struct l2cap_conn *conn;
 	u8		preq[7]; /* SMP Pairing Request */
@@ -140,6 +142,7 @@ struct smp_chan {
 	unsigned long	smp_flags;
 	struct work_struct confirm;
 	struct work_struct random;
+	struct delayed_work reencrypt;
 };
 
 /* SMP Commands */
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-02-28 14:37 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-28 14:37 [PATCH 1/2] Bluetooth: Re-encrypt link after receiving an LTK johan.hedberg
2014-02-28 14:37 ` [PATCH 2/2] Bluetooth: Delay LTK encryption to let remote receive all keys johan.hedberg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.