aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2015-03-16 04:10:23 -0400
committerJohan Hedberg <johan.hedberg@intel.com>2015-03-16 04:31:28 -0400
commit0821a2c5ab76d8ef81c1c2a8571a7ba4aa850976 (patch)
treef34c2c7caac385b2693a7ea2e0570195ba9cedad /net/bluetooth
parent60a27d653d972584e5e98ab3558c62c3d3bc547a (diff)
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,
6274 struct mgmt_rp_read_local_oob_ext_data *rp; 6274 struct mgmt_rp_read_local_oob_ext_data *rp;
6275 size_t rp_len; 6275 size_t rp_len;
6276 u16 eir_len; 6276 u16 eir_len;
6277 u8 status, flags, role, addr[7]; 6277 u8 status, flags, role, addr[7], hash[16], rand[16];
6278 int err; 6278 int err;
6279 6279
6280 BT_DBG("%s", hdev->name); 6280 BT_DBG("%s", hdev->name);
@@ -6302,7 +6302,7 @@ static int read_local_oob_ext_data(struct sock *sk, struct hci_dev *hdev,
6302 MGMT_OP_READ_LOCAL_OOB_EXT_DATA, 6302 MGMT_OP_READ_LOCAL_OOB_EXT_DATA,
6303 status, &cp->type, 6303 status, &cp->type,
6304 sizeof(cp->type)); 6304 sizeof(cp->type));
6305 eir_len = 15; 6305 eir_len = 9 + 3 + 18 + 18 + 3;
6306 break; 6306 break;
6307 default: 6307 default:
6308 return mgmt_cmd_complete(sk, hdev->id, 6308 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,
6327 hdev->dev_class, 3); 6327 hdev->dev_class, 3);
6328 break; 6328 break;
6329 case (BIT(BDADDR_LE_PUBLIC) | BIT(BDADDR_LE_RANDOM)): 6329 case (BIT(BDADDR_LE_PUBLIC) | BIT(BDADDR_LE_RANDOM)):
6330 if (smp_generate_oob(hdev, hash, rand) < 0) {
6331 hci_dev_unlock(hdev);
6332 err = mgmt_cmd_complete(sk, hdev->id,
6333 MGMT_OP_READ_LOCAL_OOB_EXT_DATA,
6334 MGMT_STATUS_FAILED,
6335 &cp->type, sizeof(cp->type));
6336 goto done;
6337 }
6338
6330 if (hci_dev_test_flag(hdev, HCI_PRIVACY)) { 6339 if (hci_dev_test_flag(hdev, HCI_PRIVACY)) {
6331 memcpy(addr, &hdev->rpa, 6); 6340 memcpy(addr, &hdev->rpa, 6);
6332 addr[6] = 0x01; 6341 addr[6] = 0x01;
@@ -6352,6 +6361,12 @@ static int read_local_oob_ext_data(struct sock *sk, struct hci_dev *hdev,
6352 eir_len = eir_append_data(rp->eir, eir_len, EIR_LE_ROLE, 6361 eir_len = eir_append_data(rp->eir, eir_len, EIR_LE_ROLE,
6353 &role, sizeof(role)); 6362 &role, sizeof(role));
6354 6363
6364 eir_len = eir_append_data(rp->eir, eir_len, EIR_LE_SC_CONFIRM,
6365 hash, sizeof(hash));
6366
6367 eir_len = eir_append_data(rp->eir, eir_len, EIR_LE_SC_RANDOM,
6368 rand, sizeof(rand));
6369
6355 flags = get_adv_discov_flags(hdev); 6370 flags = get_adv_discov_flags(hdev);
6356 6371
6357 if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) 6372 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,
6370 err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_EXT_DATA, 6385 err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_EXT_DATA,
6371 MGMT_STATUS_SUCCESS, rp, rp_len); 6386 MGMT_STATUS_SUCCESS, rp, rp_len);
6372 6387
6388done:
6373 kfree(rp); 6389 kfree(rp);
6374 6390
6375 return err; 6391 return err;