Bluetooth: Return LE SC confirm and random values for out-of-band data
authorMarcel Holtmann <marcel@holtmann.org>
Mon, 16 Mar 2015 08:10:23 +0000 (01:10 -0700)
committerJohan Hedberg <johan.hedberg@intel.com>
Mon, 16 Mar 2015 08:31:28 +0000 (10:31 +0200)
Then the local out-of-band data for LE SC pairing is requested via Read
Local OOB Extended Data command, then fill in the values generated by
the smp_generate_oob function. Every call of this command will overwrite
previously generated values.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
net/bluetooth/mgmt.c

index 6cb0a304182ff54287230cd621089c041dce4602..5322584460c1088cca3aabe1bae8df3e8793c28f 100644 (file)
@@ -6274,7 +6274,7 @@ static int read_local_oob_ext_data(struct sock *sk, struct hci_dev *hdev,
        struct mgmt_rp_read_local_oob_ext_data *rp;
        size_t rp_len;
        u16 eir_len;
-       u8 status, flags, role, addr[7];
+       u8 status, flags, role, addr[7], hash[16], rand[16];
        int err;
 
        BT_DBG("%s", hdev->name);
@@ -6302,7 +6302,7 @@ static int read_local_oob_ext_data(struct sock *sk, struct hci_dev *hdev,
                                                 MGMT_OP_READ_LOCAL_OOB_EXT_DATA,
                                                 status, &cp->type,
                                                 sizeof(cp->type));
-               eir_len = 15;
+               eir_len = 9 + 3 + 18 + 18 + 3;
                break;
        default:
                return mgmt_cmd_complete(sk, hdev->id,
@@ -6327,6 +6327,15 @@ static int read_local_oob_ext_data(struct sock *sk, struct hci_dev *hdev,
                                          hdev->dev_class, 3);
                break;
        case (BIT(BDADDR_LE_PUBLIC) | BIT(BDADDR_LE_RANDOM)):
+               if (smp_generate_oob(hdev, hash, rand) < 0) {
+                       hci_dev_unlock(hdev);
+                       err = mgmt_cmd_complete(sk, hdev->id,
+                                        MGMT_OP_READ_LOCAL_OOB_EXT_DATA,
+                                        MGMT_STATUS_FAILED,
+                                        &cp->type, sizeof(cp->type));
+                       goto done;
+               }
+
                if (hci_dev_test_flag(hdev, HCI_PRIVACY)) {
                        memcpy(addr, &hdev->rpa, 6);
                        addr[6] = 0x01;
@@ -6352,6 +6361,12 @@ static int read_local_oob_ext_data(struct sock *sk, struct hci_dev *hdev,
                eir_len = eir_append_data(rp->eir, eir_len, EIR_LE_ROLE,
                                          &role, sizeof(role));
 
+               eir_len = eir_append_data(rp->eir, eir_len, EIR_LE_SC_CONFIRM,
+                                         hash, sizeof(hash));
+
+               eir_len = eir_append_data(rp->eir, eir_len, EIR_LE_SC_RANDOM,
+                                         rand, sizeof(rand));
+
                flags = get_adv_discov_flags(hdev);
 
                if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
@@ -6370,6 +6385,7 @@ static int read_local_oob_ext_data(struct sock *sk, struct hci_dev *hdev,
        err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_EXT_DATA,
                                MGMT_STATUS_SUCCESS, rp, rp_len);
 
+done:
        kfree(rp);
 
        return err;