Bluetooth: Add support for rotating RPA
If privacy is enabled we always use RPA, even for active scan. This makes single point of controlling current random address making code simple and not prone to subtle bugs with concurent advertising, scanning and connecting. Currently used RPA is rotated to improve privacy. Timeout value is controlled by Kconfig and by default is 900 seconds (15 minutes). Change-Id: I27a15666a4f2e2962cf6eb20c7cd06f90b7f2bb1 Signed-off-by: Szymon Janc <ext.szymon.janc@tieto.com>
This commit is contained in:
parent
0022289ace
commit
a0a52691f2
10 changed files with 97 additions and 31 deletions
|
@ -182,6 +182,15 @@ config BLUETOOTH_PRIVACY
|
||||||
Enable local Privacy Feature support. This makes it possible
|
Enable local Privacy Feature support. This makes it possible
|
||||||
to use Resolvable Private Addresses (RPAs).
|
to use Resolvable Private Addresses (RPAs).
|
||||||
|
|
||||||
|
config BLUETOOTH_RPA_TIMEOUT
|
||||||
|
int "Resolvable Private Address timeout"
|
||||||
|
depends on BLUETOOTH_PRIVACY
|
||||||
|
default 900
|
||||||
|
range 1 65535
|
||||||
|
help
|
||||||
|
This option defines how often resolvable private address is rotated.
|
||||||
|
Value is provided in seconds and defaults to 900 seconds (15 minutes).
|
||||||
|
|
||||||
config BLUETOOTH_SIGNING
|
config BLUETOOTH_SIGNING
|
||||||
bool "Data signing support"
|
bool "Data signing support"
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <misc/byteorder.h>
|
#include <misc/byteorder.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
|
#include <misc/nano_work.h>
|
||||||
|
|
||||||
#include <bluetooth/log.h>
|
#include <bluetooth/log.h>
|
||||||
#include <bluetooth/hci.h>
|
#include <bluetooth/hci.h>
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <misc/byteorder.h>
|
#include <misc/byteorder.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
|
#include <misc/nano_work.h>
|
||||||
|
|
||||||
#include <bluetooth/log.h>
|
#include <bluetooth/log.h>
|
||||||
#include <bluetooth/hci.h>
|
#include <bluetooth/hci.h>
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <misc/byteorder.h>
|
#include <misc/byteorder.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
|
#include <misc/nano_work.h>
|
||||||
|
|
||||||
#include <bluetooth/log.h>
|
#include <bluetooth/log.h>
|
||||||
#include <bluetooth/hci.h>
|
#include <bluetooth/hci.h>
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
#include <misc/byteorder.h>
|
#include <misc/byteorder.h>
|
||||||
#include <misc/stack.h>
|
#include <misc/stack.h>
|
||||||
|
#include <misc/nano_work.h>
|
||||||
|
|
||||||
#ifdef CONFIG_MICROKERNEL
|
#ifdef CONFIG_MICROKERNEL
|
||||||
#include <microkernel.h>
|
#include <microkernel.h>
|
||||||
|
@ -61,6 +62,7 @@
|
||||||
|
|
||||||
/* Peripheral timeout to initialize Connection Parameter Update procedure */
|
/* Peripheral timeout to initialize Connection Parameter Update procedure */
|
||||||
#define CONN_UPDATE_TIMEOUT (5 * sys_clock_ticks_per_sec)
|
#define CONN_UPDATE_TIMEOUT (5 * sys_clock_ticks_per_sec)
|
||||||
|
#define RPA_TIMEOUT (CONFIG_BLUETOOTH_RPA_TIMEOUT * sys_clock_ticks_per_sec)
|
||||||
|
|
||||||
/* Stacks for the fibers */
|
/* Stacks for the fibers */
|
||||||
static BT_STACK_NOINIT(rx_fiber_stack, CONFIG_BLUETOOTH_RX_STACK_SIZE);
|
static BT_STACK_NOINIT(rx_fiber_stack, CONFIG_BLUETOOTH_RX_STACK_SIZE);
|
||||||
|
@ -433,6 +435,67 @@ static int set_random_address(const bt_addr_t *addr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_BLUETOOTH_PRIVACY)
|
||||||
|
/* this function sets new RPA only if current one is no longer valid */
|
||||||
|
static int le_set_rpa(void)
|
||||||
|
{
|
||||||
|
bt_addr_t rpa;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* work is not idle so current RPA is valid */
|
||||||
|
if (!atomic_test_bit(bt_dev.rpa_update.work.flags,
|
||||||
|
NANO_WORK_STATE_IDLE)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = bt_smp_create_rpa(bt_dev.irk, &rpa);
|
||||||
|
if (!err) {
|
||||||
|
err = set_random_address(&rpa);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restart timer even if failed to set new RPA */
|
||||||
|
nano_delayed_work_submit(&bt_dev.rpa_update, RPA_TIMEOUT);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpa_timeout(struct nano_work *work)
|
||||||
|
{
|
||||||
|
BT_DBG("");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* we need to update rpa only if advertising is ongoing, with
|
||||||
|
* BT_DEV_KEEP_ADVERTISING flag is handled in disconnected event
|
||||||
|
*/
|
||||||
|
if (atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) {
|
||||||
|
/* make sure new address is used */
|
||||||
|
set_advertise_disable();
|
||||||
|
le_set_rpa();
|
||||||
|
set_advertise_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)) {
|
||||||
|
/* TODO do we need to toggle scan? */
|
||||||
|
le_set_rpa();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int le_set_nrpa(void)
|
||||||
|
{
|
||||||
|
bt_addr_t nrpa;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = bt_rand(nrpa.val, sizeof(nrpa.val));
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
nrpa.val[5] &= 0x3f;
|
||||||
|
|
||||||
|
return set_random_address(&nrpa);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_BLUETOOTH_CONN)
|
#if defined(CONFIG_BLUETOOTH_CONN)
|
||||||
static void hci_acl(struct net_buf *buf)
|
static void hci_acl(struct net_buf *buf)
|
||||||
{
|
{
|
||||||
|
@ -588,6 +651,9 @@ static void hci_disconn_complete(struct net_buf *buf)
|
||||||
|
|
||||||
advertise:
|
advertise:
|
||||||
if (atomic_test_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING)) {
|
if (atomic_test_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING)) {
|
||||||
|
#if defined(CONFIG_BLUETOOTH_PRIVACY)
|
||||||
|
le_set_rpa();
|
||||||
|
#endif
|
||||||
set_advertise_enable();
|
set_advertise_enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -851,21 +917,6 @@ static void le_conn_update_complete(struct net_buf *buf)
|
||||||
bt_conn_unref(conn);
|
bt_conn_unref(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_BLUETOOTH_PRIVACY)
|
|
||||||
static int le_set_rpa(void)
|
|
||||||
{
|
|
||||||
bt_addr_t rpa;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = bt_smp_create_rpa(bt_dev.irk, &rpa);
|
|
||||||
if (err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return set_random_address(&rpa);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void check_pending_conn(const bt_addr_le_t *id_addr,
|
static void check_pending_conn(const bt_addr_le_t *id_addr,
|
||||||
const bt_addr_le_t *addr, uint8_t evtype)
|
const bt_addr_le_t *addr, uint8_t evtype)
|
||||||
{
|
{
|
||||||
|
@ -2313,21 +2364,6 @@ int bt_rand(void *buf, size_t len)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int le_set_nrpa(void)
|
|
||||||
{
|
|
||||||
bt_addr_t nrpa;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = bt_rand(nrpa.val, sizeof(nrpa.val));
|
|
||||||
if (err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
nrpa.val[5] &= 0x3f;
|
|
||||||
|
|
||||||
return set_random_address(&nrpa);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
|
static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
|
||||||
uint8_t filter_dup)
|
uint8_t filter_dup)
|
||||||
{
|
{
|
||||||
|
@ -2354,6 +2390,13 @@ static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
|
||||||
set_param->filter_policy = 0x00;
|
set_param->filter_policy = 0x00;
|
||||||
|
|
||||||
if (scan_type == BT_HCI_LE_SCAN_ACTIVE) {
|
if (scan_type == BT_HCI_LE_SCAN_ACTIVE) {
|
||||||
|
#if defined(CONFIG_BLUETOOTH_PRIVACY)
|
||||||
|
err = le_set_rpa();
|
||||||
|
if (err) {
|
||||||
|
net_buf_unref(buf);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
#else
|
||||||
/* only set NRPA if there is no advertising ongoing */
|
/* only set NRPA if there is no advertising ongoing */
|
||||||
if (!atomic_test_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING)) {
|
if (!atomic_test_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING)) {
|
||||||
err = le_set_nrpa();
|
err = le_set_nrpa();
|
||||||
|
@ -2362,6 +2405,7 @@ static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
set_param->addr_type = BT_ADDR_LE_RANDOM;
|
set_param->addr_type = BT_ADDR_LE_RANDOM;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3313,6 +3357,8 @@ static int bt_init(void)
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nano_delayed_work_init(&bt_dev.rpa_update, rpa_timeout);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bt_monitor_send(BT_MONITOR_OPEN_INDEX, NULL, 0);
|
bt_monitor_send(BT_MONITOR_OPEN_INDEX, NULL, 0);
|
||||||
|
@ -3603,11 +3649,12 @@ int bt_le_adv_stop(void)
|
||||||
|
|
||||||
atomic_clear_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING);
|
atomic_clear_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING);
|
||||||
|
|
||||||
|
#if !defined(CONFIG_BLUETOOTH_PRIVACY)
|
||||||
/* If active scan is ongoing set NRPA */
|
/* If active scan is ongoing set NRPA */
|
||||||
if (atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)) {
|
if (atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)) {
|
||||||
le_set_nrpa();
|
le_set_nrpa();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,9 @@ struct bt_dev {
|
||||||
#if defined(CONFIG_BLUETOOTH_PRIVACY)
|
#if defined(CONFIG_BLUETOOTH_PRIVACY)
|
||||||
/* Local Identity Resolving Key */
|
/* Local Identity Resolving Key */
|
||||||
uint8_t irk[16];
|
uint8_t irk[16];
|
||||||
|
|
||||||
|
/* Work used for RPA rotation */
|
||||||
|
struct nano_delayed_work rpa_update;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <microkernel/task.h>
|
#include <microkernel/task.h>
|
||||||
#include <misc/byteorder.h>
|
#include <misc/byteorder.h>
|
||||||
|
#include <misc/nano_work.h>
|
||||||
#include <tinycrypt/utils.h>
|
#include <tinycrypt/utils.h>
|
||||||
#include <tinycrypt/ecc.h>
|
#include <tinycrypt/ecc.h>
|
||||||
#include <tinycrypt/ecc_dh.h>
|
#include <tinycrypt/ecc_dh.h>
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <nanokernel.h>
|
#include <nanokernel.h>
|
||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
|
#include <misc/nano_work.h>
|
||||||
|
|
||||||
#include <bluetooth/log.h>
|
#include <bluetooth/log.h>
|
||||||
#include <bluetooth/bluetooth.h>
|
#include <bluetooth/bluetooth.h>
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <misc/byteorder.h>
|
#include <misc/byteorder.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
|
#include <misc/nano_work.h>
|
||||||
|
|
||||||
#include <bluetooth/log.h>
|
#include <bluetooth/log.h>
|
||||||
#include <bluetooth/hci.h>
|
#include <bluetooth/hci.h>
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <misc/byteorder.h>
|
#include <misc/byteorder.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
|
#include <misc/nano_work.h>
|
||||||
|
|
||||||
#include <bluetooth/log.h>
|
#include <bluetooth/log.h>
|
||||||
#include <bluetooth/hci.h>
|
#include <bluetooth/hci.h>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue