aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-02-28 11:10:02 -0500
committerMarcel Holtmann <marcel@holtmann.org>2014-02-28 11:17:46 -0500
commit38ccdc93326f61b84734028e586ed522a53b733a (patch)
tree98353cfea0cd3e34c7beb6df3b5227481742f01a /net/bluetooth
parent9489eca4ab2fd5d9bbf3bab992168cc8107fc3e9 (diff)
Bluetooth: Re-encrypt link after receiving an LTK
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> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/smp.c32
-rw-r--r--net/bluetooth/smp.h3
2 files changed, 29 insertions, 6 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 4f4ff36f5f34..e119d76f87a7 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1178,6 +1178,7 @@ int smp_distribute_keys(struct l2cap_conn *conn)
1178 struct smp_chan *smp = conn->smp_chan; 1178 struct smp_chan *smp = conn->smp_chan;
1179 struct hci_conn *hcon = conn->hcon; 1179 struct hci_conn *hcon = conn->hcon;
1180 struct hci_dev *hdev = hcon->hdev; 1180 struct hci_dev *hdev = hcon->hdev;
1181 bool ltk_encrypt;
1181 __u8 *keydist; 1182 __u8 *keydist;
1182 1183
1183 BT_DBG("conn %p", conn); 1184 BT_DBG("conn %p", conn);
@@ -1269,12 +1270,33 @@ int smp_distribute_keys(struct l2cap_conn *conn)
1269 if ((smp->remote_key_dist & 0x07)) 1270 if ((smp->remote_key_dist & 0x07))
1270 return 0; 1271 return 0;
1271 1272
1272 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags); 1273 /* Check if we should try to re-encrypt the link with the LTK.
1273 cancel_delayed_work_sync(&conn->security_timer); 1274 * SMP_FLAG_LTK_ENCRYPT flag is used to track whether we've
1274 set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags); 1275 * already tried this (in which case we shouldn't try again).
1275 smp_notify_keys(conn); 1276 *
1277 * The request will trigger an encryption key refresh event
1278 * which will cause a call to auth_cfm and eventually lead to
1279 * l2cap_core.c calling this smp_distribute_keys function again
1280 * and thereby completing the process.
1281 */
1282 if (smp->ltk)
1283 ltk_encrypt = !test_and_set_bit(SMP_FLAG_LTK_ENCRYPT,
1284 &smp->smp_flags);
1285 else
1286 ltk_encrypt = false;
1276 1287
1277 smp_chan_destroy(conn); 1288 /* Re-encrypt the link with LTK if possible */
1289 if (ltk_encrypt && hcon->out) {
1290 struct smp_ltk *ltk = smp->ltk;
1291 hci_le_start_enc(hcon, ltk->ediv, ltk->rand, ltk->val);
1292 hcon->enc_key_size = ltk->enc_size;
1293 } else {
1294 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1295 cancel_delayed_work_sync(&conn->security_timer);
1296 set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
1297 smp_notify_keys(conn);
1298 smp_chan_destroy(conn);
1299 }
1278 1300
1279 return 0; 1301 return 0;
1280} 1302}
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 {
118#define SMP_FLAG_TK_VALID 1 118#define SMP_FLAG_TK_VALID 1
119#define SMP_FLAG_CFM_PENDING 2 119#define SMP_FLAG_CFM_PENDING 2
120#define SMP_FLAG_MITM_AUTH 3 120#define SMP_FLAG_MITM_AUTH 3
121#define SMP_FLAG_COMPLETE 4 121#define SMP_FLAG_LTK_ENCRYPT 4
122#define SMP_FLAG_COMPLETE 5
122 123
123struct smp_chan { 124struct smp_chan {
124 struct l2cap_conn *conn; 125 struct l2cap_conn *conn;