Bluetooth: Set SMP OOB flag if OOB data is available
authorJohan Hedberg <johan.hedberg@intel.com>
Sun, 26 Oct 2014 20:19:10 +0000 (21:19 +0100)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 3 Dec 2014 15:51:21 +0000 (16:51 +0100)
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>
net/bluetooth/smp.c

index 589e015..0c2214a 100644 (file)
@@ -57,6 +57,7 @@ enum {
        SMP_FLAG_DEBUG_KEY,
        SMP_FLAG_WAIT_USER,
        SMP_FLAG_DHKEY_PENDING,
+       SMP_FLAG_OOB,
 };
 
 struct smp_chan {
@@ -562,7 +563,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
        struct smp_chan *smp = chan->data;
        struct hci_conn *hcon = conn->hcon;
        struct hci_dev *hdev = hcon->hdev;
-       u8 local_dist = 0, remote_dist = 0;
+       u8 local_dist = 0, remote_dist = 0, oob_flag = SMP_OOB_NOT_PRESENT;
 
        if (test_bit(HCI_BONDABLE, &conn->hcon->hdev->dev_flags)) {
                local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
@@ -578,19 +579,37 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
        if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
                local_dist |= SMP_DIST_ID_KEY;
 
-       if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
-               if ((authreq & SMP_AUTH_SC) &&
-                   test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
+       if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags) &&
+           (authreq & SMP_AUTH_SC)) {
+               struct oob_data *oob_data;
+               u8 bdaddr_type;
+
+               if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
                        local_dist |= SMP_DIST_LINK_KEY;
                        remote_dist |= SMP_DIST_LINK_KEY;
                }
+
+               if (hcon->dst_type == ADDR_LE_DEV_PUBLIC)
+                       bdaddr_type = BDADDR_LE_PUBLIC;
+               else
+                       bdaddr_type = BDADDR_LE_RANDOM;
+
+               oob_data = hci_find_remote_oob_data(hdev, &hcon->dst,
+                                                   bdaddr_type);
+               if (oob_data) {
+                       set_bit(SMP_FLAG_OOB, &smp->flags);
+                       oob_flag = SMP_OOB_PRESENT;
+                       memcpy(smp->rrnd, oob_data->rand256, 16);
+                       memcpy(smp->pcnf, oob_data->hash256, 16);
+               }
+
        } else {
                authreq &= ~SMP_AUTH_SC;
        }
 
        if (rsp == NULL) {
                req->io_capability = conn->hcon->io_capability;
-               req->oob_flag = SMP_OOB_NOT_PRESENT;
+               req->oob_flag = oob_flag;
                req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
                req->init_key_dist = local_dist;
                req->resp_key_dist = remote_dist;
@@ -601,7 +620,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
        }
 
        rsp->io_capability = conn->hcon->io_capability;
-       rsp->oob_flag = SMP_OOB_NOT_PRESENT;
+       rsp->oob_flag = oob_flag;
        rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
        rsp->init_key_dist = req->init_key_dist & remote_dist;
        rsp->resp_key_dist = req->resp_key_dist & local_dist;