summaryrefslogtreecommitdiff
path: root/net/bluetooth
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2014-02-24 08:25:54 +0400
committerJohan Hedberg <johan.hedberg@intel.com>2014-02-24 10:45:58 +0400
commit94b1fc92cd7cf550460ffd4bcc08c2707564aa49 (patch)
tree6288fa61c03d3139540e007ccdb2fa6c9d30dbbf /net/bluetooth
parentac345813c4ac5a0e66261e9812f0fe94729c0eb2 (diff)
downloadlinux-94b1fc92cd7cf550460ffd4bcc08c2707564aa49.tar.xz
Bluetooth: Use unresolvable private address for active scanning
When running active scanning during LE discovery, do not reveal the own identity to the peer devices. In case LE privacy has been enabled, then a resolvable private address is used. If the LE privacy option is off, then use an unresolvable private address. The public address or static random address is never used in active scanning anymore. This ensures that scan request are send using a random address. 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/hci_conn.c5
-rw-r--r--net/bluetooth/hci_core.c18
-rw-r--r--net/bluetooth/mgmt.c8
3 files changed, 27 insertions, 4 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index a1efa1c62de8..3d6b1cf07d23 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -563,7 +563,10 @@ static int hci_create_le_conn(struct hci_conn *conn)
memset(&cp, 0, sizeof(cp));
- err = hci_update_random_address(&req, &own_addr_type);
+ /* Update random address, but set require_privacy to false so
+ * that we never connect with an unresolvable address.
+ */
+ err = hci_update_random_address(&req, false, &own_addr_type);
if (err < 0)
return err;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 80462a126ebd..31e68ade309d 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3332,7 +3332,8 @@ static void le_scan_disable_work(struct work_struct *work)
BT_ERR("Disable LE scanning request failed: err %d", err);
}
-int hci_update_random_address(struct hci_request *req, u8 *own_addr_type)
+int hci_update_random_address(struct hci_request *req, bool require_privacy,
+ u8 *own_addr_type)
{
struct hci_dev *hdev = req->hdev;
int err;
@@ -3365,6 +3366,21 @@ int hci_update_random_address(struct hci_request *req, u8 *own_addr_type)
return 0;
}
+ /* In case of required privacy without resolvable private address,
+ * use an unresolvable private address. This is useful for active
+ * scanning and non-connectable advertising.
+ */
+ if (require_privacy) {
+ bdaddr_t urpa;
+
+ get_random_bytes(&urpa, 6);
+ urpa.b[5] &= 0x3f; /* Clear two most significant bits */
+
+ *own_addr_type = ADDR_LE_DEV_RANDOM;
+ hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, &urpa);
+ return 0;
+ }
+
/* If forcing static address is in use or there is no public
* address use the static address as random address (but skip
* the HCI command if the current random address is already the
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 37305facf4d6..5d309d4ab527 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -844,7 +844,7 @@ static void enable_advertising(struct hci_request *req)
memset(&cp, 0, sizeof(cp));
- if (hci_update_random_address(req, &own_addr_type) < 0)
+ if (hci_update_random_address(req, false, &own_addr_type) < 0)
return;
cp.min_interval = __constant_cpu_to_le16(0x0800);
@@ -3389,7 +3389,11 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
memset(&param_cp, 0, sizeof(param_cp));
- err = hci_update_random_address(&req, &own_addr_type);
+ /* All active scans will be done with either a resolvable
+ * private address (when privacy feature has been enabled)
+ * or unresolvable private address.
+ */
+ err = hci_update_random_address(&req, true, &own_addr_type);
if (err < 0) {
err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
MGMT_STATUS_FAILED);