aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2015-03-16 01:10:23 -0700
committerJohan Hedberg <johan.hedberg@intel.com>2015-03-16 10:31:28 +0200
commit0821a2c5ab76d8ef81c1c2a8571a7ba4aa850976 (patch)
treef34c2c7caac385b2693a7ea2e0570195ba9cedad /net/bluetooth
parentBluetooth: Add function for generating LE SC out-of-band data (diff)
downloadlinux-dev-0821a2c5ab76d8ef81c1c2a8571a7ba4aa850976.tar.xz
linux-dev-0821a2c5ab76d8ef81c1c2a8571a7ba4aa850976.zip
Bluetooth: Return LE SC confirm and random values for out-of-band data
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>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/mgmt.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 6cb0a304182f..5322584460c1 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -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;