aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-10-26 16:19:10 -0400
committerMarcel Holtmann <marcel@holtmann.org>2014-12-03 10:51:21 -0500
commit02b05bd8b0a632e9a26795bced8f19ca6a5f7079 (patch)
tree9f4bc255c0d95e21409ec0c091cc42d904002054 /net/bluetooth
parent86df9200c77f46a246ca4a78949887eb6dbde091 (diff)
Bluetooth: Set SMP OOB flag if OOB data is available
If we have OOB data available for the remote device in question we should set the OOB flag appropriately in the SMP pairing request or response. 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.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 589e015c5125..0c2214a41816 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -57,6 +57,7 @@ enum {
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 SMP_FLAG_DHKEY_PENDING,
60 SMP_FLAG_OOB,
60}; 61};
61 62
62struct smp_chan { 63struct smp_chan {
@@ -562,7 +563,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
562 struct smp_chan *smp = chan->data; 563 struct smp_chan *smp = chan->data;
563 struct hci_conn *hcon = conn->hcon; 564 struct hci_conn *hcon = conn->hcon;
564 struct hci_dev *hdev = hcon->hdev; 565 struct hci_dev *hdev = hcon->hdev;
565 u8 local_dist = 0, remote_dist = 0; 566 u8 local_dist = 0, remote_dist = 0, oob_flag = SMP_OOB_NOT_PRESENT;
566 567
567 if (test_bit(HCI_BONDABLE, &conn->hcon->hdev->dev_flags)) { 568 if (test_bit(HCI_BONDABLE, &conn->hcon->hdev->dev_flags)) {
568 local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 569 local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
@@ -578,19 +579,37 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
578 if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) 579 if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
579 local_dist |= SMP_DIST_ID_KEY; 580 local_dist |= SMP_DIST_ID_KEY;
580 581
581 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) { 582 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags) &&
582 if ((authreq & SMP_AUTH_SC) && 583 (authreq & SMP_AUTH_SC)) {
583 test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { 584 struct oob_data *oob_data;
585 u8 bdaddr_type;
586
587 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
584 local_dist |= SMP_DIST_LINK_KEY; 588 local_dist |= SMP_DIST_LINK_KEY;
585 remote_dist |= SMP_DIST_LINK_KEY; 589 remote_dist |= SMP_DIST_LINK_KEY;
586 } 590 }
591
592 if (hcon->dst_type == ADDR_LE_DEV_PUBLIC)
593 bdaddr_type = BDADDR_LE_PUBLIC;
594 else
595 bdaddr_type = BDADDR_LE_RANDOM;
596
597 oob_data = hci_find_remote_oob_data(hdev, &hcon->dst,
598 bdaddr_type);
599 if (oob_data) {
600 set_bit(SMP_FLAG_OOB, &smp->flags);
601 oob_flag = SMP_OOB_PRESENT;
602 memcpy(smp->rrnd, oob_data->rand256, 16);
603 memcpy(smp->pcnf, oob_data->hash256, 16);
604 }
605
587 } else { 606 } else {
588 authreq &= ~SMP_AUTH_SC; 607 authreq &= ~SMP_AUTH_SC;
589 } 608 }
590 609
591 if (rsp == NULL) { 610 if (rsp == NULL) {
592 req->io_capability = conn->hcon->io_capability; 611 req->io_capability = conn->hcon->io_capability;
593 req->oob_flag = SMP_OOB_NOT_PRESENT; 612 req->oob_flag = oob_flag;
594 req->max_key_size = SMP_MAX_ENC_KEY_SIZE; 613 req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
595 req->init_key_dist = local_dist; 614 req->init_key_dist = local_dist;
596 req->resp_key_dist = remote_dist; 615 req->resp_key_dist = remote_dist;
@@ -601,7 +620,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
601 } 620 }
602 621
603 rsp->io_capability = conn->hcon->io_capability; 622 rsp->io_capability = conn->hcon->io_capability;
604 rsp->oob_flag = SMP_OOB_NOT_PRESENT; 623 rsp->oob_flag = oob_flag;
605 rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; 624 rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
606 rsp->init_key_dist = req->init_key_dist & remote_dist; 625 rsp->init_key_dist = req->init_key_dist & remote_dist;
607 rsp->resp_key_dist = req->resp_key_dist & local_dist; 626 rsp->resp_key_dist = req->resp_key_dist & local_dist;