aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-06-04 04:07:40 -0400
committerMarcel Holtmann <marcel@holtmann.org>2014-12-03 10:51:19 -0500
commitd3e54a876e35120b3355e22d78861e73a6acab6f (patch)
tree05913c51782ceded2fcd6ed1fcba3b109a2facdf /net/bluetooth
parent38606f1418cc9c0ac4230f4d9133a2cae5e02416 (diff)
Bluetooth: Fix DHKey Check sending order for slave role
According to the LE SC specification the initiating device sends its DHKey check first and the non-initiating devices sends its DHKey check as a response to this. It's also important that the non-initiating device doesn't send the response if it's still waiting for user input. In order to synchronize all this a new flag is added. 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.c60
1 files changed, 43 insertions, 17 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 8cfa1c1b205c..9a4ce4581475 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -56,6 +56,7 @@ enum {
56 SMP_FLAG_REMOTE_PK, 56 SMP_FLAG_REMOTE_PK,
57 SMP_FLAG_DEBUG_KEY, 57 SMP_FLAG_DEBUG_KEY,
58 SMP_FLAG_WAIT_USER, 58 SMP_FLAG_WAIT_USER,
59 SMP_FLAG_DHKEY_PENDING,
59}; 60};
60 61
61struct smp_chan { 62struct smp_chan {
@@ -994,6 +995,29 @@ static void smp_notify_keys(struct l2cap_conn *conn)
994 } 995 }
995} 996}
996 997
998static void sc_add_ltk(struct smp_chan *smp)
999{
1000 struct hci_conn *hcon = smp->conn->hcon;
1001 u8 key_type, auth;
1002
1003 if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
1004 key_type = SMP_LTK_P256_DEBUG;
1005 else
1006 key_type = SMP_LTK_P256;
1007
1008 if (hcon->pending_sec_level == BT_SECURITY_FIPS)
1009 auth = 1;
1010 else
1011 auth = 0;
1012
1013 memset(smp->tk + smp->enc_key_size, 0,
1014 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
1015
1016 smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
1017 key_type, auth, smp->tk, smp->enc_key_size,
1018 0, 0);
1019}
1020
997static void sc_generate_link_key(struct smp_chan *smp) 1021static void sc_generate_link_key(struct smp_chan *smp)
998{ 1022{
999 /* These constants are as specified in the core specification. 1023 /* These constants are as specified in the core specification.
@@ -1312,12 +1336,10 @@ static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op)
1312 if (!hcon->out) { 1336 if (!hcon->out) {
1313 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 1337 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
1314 sizeof(smp->prnd), smp->prnd); 1338 sizeof(smp->prnd), smp->prnd);
1315 if (smp->passkey_round == 20) { 1339 if (smp->passkey_round == 20)
1316 sc_dhkey_check(smp);
1317 SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 1340 SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1318 } else { 1341 else
1319 SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 1342 SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
1320 }
1321 return 0; 1343 return 0;
1322 } 1344 }
1323 1345
@@ -1394,7 +1416,14 @@ static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey)
1394 return 0; 1416 return 0;
1395 } 1417 }
1396 1418
1397 sc_dhkey_check(smp); 1419 /* Initiator sends DHKey check first */
1420 if (hcon->out) {
1421 sc_dhkey_check(smp);
1422 SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1423 } else if (test_and_clear_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags)) {
1424 sc_dhkey_check(smp);
1425 sc_add_ltk(smp);
1426 }
1398 1427
1399 return 0; 1428 return 0;
1400} 1429}
@@ -2262,7 +2291,6 @@ static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)
2262 struct smp_chan *smp = chan->data; 2291 struct smp_chan *smp = chan->data;
2263 u8 a[7], b[7], *local_addr, *remote_addr; 2292 u8 a[7], b[7], *local_addr, *remote_addr;
2264 u8 io_cap[3], r[16], e[16]; 2293 u8 io_cap[3], r[16], e[16];
2265 u8 key_type, auth;
2266 int err; 2294 int err;
2267 2295
2268 BT_DBG("conn %p", conn); 2296 BT_DBG("conn %p", conn);
@@ -2298,19 +2326,17 @@ static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)
2298 if (memcmp(check->e, e, 16)) 2326 if (memcmp(check->e, e, 16))
2299 return SMP_DHKEY_CHECK_FAILED; 2327 return SMP_DHKEY_CHECK_FAILED;
2300 2328
2301 if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags)) 2329 if (!hcon->out) {
2302 key_type = SMP_LTK_P256_DEBUG; 2330 if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) {
2303 else 2331 set_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags);
2304 key_type = SMP_LTK_P256; 2332 return 0;
2333 }
2305 2334
2306 if (hcon->pending_sec_level == BT_SECURITY_FIPS) 2335 /* Slave sends DHKey check as response to master */
2307 auth = 1; 2336 sc_dhkey_check(smp);
2308 else 2337 }
2309 auth = 0;
2310 2338
2311 smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, 2339 sc_add_ltk(smp);
2312 key_type, auth, smp->tk, smp->enc_key_size,
2313 0, 0);
2314 2340
2315 if (hcon->out) { 2341 if (hcon->out) {
2316 hci_le_start_enc(hcon, 0, 0, smp->tk); 2342 hci_le_start_enc(hcon, 0, 0, smp->tk);