Skip to content

Commit

Permalink
NimBLE host: Add Non-Resolvable Private address support
Browse files Browse the repository at this point in the history
- Add NRPA support to existing Host based Privacy framework
  • Loading branch information
prasad-alatkar authored and ESPAbhinav committed Feb 14, 2024
1 parent 9fd99b3 commit 7f59d1f
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 17 deletions.
34 changes: 29 additions & 5 deletions nimble/host/include/host/ble_hs_pvcy.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,36 @@ extern "C" {
#endif

#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY)
/* Called to configure local(own) privacy (RPA) when using host based privacy. In
* Host based privacy as controller is not aware of RPA, we do it via
* 'BLE_ADDR_RANDOM' addr_type route.

#define NIMBLE_HOST_DISABLE_PRIVACY 0x00
#define NIMBLE_HOST_ENABLE_RPA 0x01
#define NIMBLE_HOST_ENABLE_NRPA 0x02

/* Called to configure local(own) privacy (RPA/NRPA) when using Host based privacy.
* In Host based privacy, as controller is not aware of RPA/NRPA address is in use,
* we do it through 'BLE_ADDR_RANDOM (0x01)' addr_type route. This is necessary
* so as to set the private address as random address in controller.
* Remember to configure `BLE_SM_PAIR_KEY_DIST_ID` in our & their
* key distributions for using RPA. For NRPA part of privacy it is not
* necessary to configure key distributions in host, as anyway NRPA is non-resolvable.
* Please call this API once host-controller are synced as we set the private
* (RPA/NRPA) address using host-controller HCI commands.
*
* To give brief information on how to use this feature,
* please refer to following steps while using RPA feature:
*
* 1. Include "host/ble_hs_pvcy.h".
* 2. Set own_addr_type to `BLE_OWN_ADDR_RANDOM`.
* 3. Add `BLE_SM_PAIR_KEY_DIST_ID` to key distribution in
* `ble_hs_cfg.sm_our_key_dist` & `ble_hs_cfg.sm_their_key_dist`.
* 4. Call `ble_hs_pvcy_rpa_config(1)` in Host-Controller sync callback.
*
* In case of NRPA, steps 1, 2 and calling ble_hs_pvcy_rpa_config(2) will
* suffice.
*
* @param enable RPA when enable is not 0
* disable RPA otherwise
* @param enable RPA when param = 1 (NIMBLE_HOST_ENABLE_RPA)
* enable NRPA when param = 2 (NIMBLE_HOST_ENABLE_NRPA)
* disable privacy when param = 0 (NIMBLE_HOST_DISABLE_PRIVACY)
*
* @return return 0 when successful.
* return appropriate error code otherwise
Expand Down
31 changes: 31 additions & 0 deletions nimble/host/src/ble_hs_id.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,37 @@ ble_hs_id_gen_rnd(int nrpa, ble_addr_t *out_addr)
}

#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY)
/**
* Sets the device's pseudo Non Resolvable Private Address when 'Host based
* privacy' is in use.
*
* @return 0 on success;
* Appropriate error code if failure.
*/
int
ble_hs_id_set_nrpa_rnd()
{

ble_addr_t nrpa_addr;
int rc;

ble_hs_id_gen_rnd(1, &nrpa_addr);

ble_hs_lock();

/* set the NRPA address as pseudo random address in controller */
rc = ble_hs_hci_util_set_random_addr(nrpa_addr.val);
if (rc != 0) {
goto done;
}

memcpy(ble_hs_id_rnd, nrpa_addr.val, BLE_DEV_ADDR_LEN);

done:
ble_hs_unlock();
return rc;
}

/**
* Sets the device's pseudo RPA address when 'Host based privacy' is in use.
* The address type (RPA) is inferred from the most-significant bits. The
Expand Down
1 change: 1 addition & 0 deletions nimble/host/src/ble_hs_id_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ void ble_hs_id_rnd_reset(void);
#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY)
bool ble_hs_is_rpa(uint8_t *addr, uint8_t addr_type);
int ble_hs_id_set_pseudo_rnd(const uint8_t *);
int ble_hs_id_set_nrpa_rnd(void);
#endif
#ifdef __cplusplus
}
Expand Down
12 changes: 10 additions & 2 deletions nimble/host/src/ble_hs_pvcy.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "stats/stats.h"
#include "ble_hs_priv.h"
#include "ble_hs_resolv_priv.h"
#include "host/ble_hs_pvcy.h"

static uint8_t ble_hs_pvcy_started;
static uint8_t ble_hs_pvcy_irk[16];
Expand Down Expand Up @@ -307,16 +308,23 @@ ble_hs_pvcy_rpa_config(uint8_t enable)
{
int rc = 0;

if (enable != 0) {
if (enable != NIMBLE_HOST_DISABLE_PRIVACY) {
rc = ble_hs_pvcy_ensure_started();
if (rc != 0) {
return rc;
}

ble_hs_resolv_enable(true);

/* Configure NRPA address related flags according to input parameter */
if (enable == NIMBLE_HOST_ENABLE_NRPA) {
ble_hs_resolv_nrpa_enable();
} else {
ble_hs_resolv_nrpa_disable();
}

/* Generate local RPA address and set it in controller */
rc = ble_hs_gen_own_rpa_random();
rc = ble_hs_gen_own_private_rnd();
} else {
ble_hs_resolv_enable(false);
}
Expand Down
45 changes: 36 additions & 9 deletions nimble/host/src/ble_hs_resolv.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ struct ble_hs_resolv_data {
struct ble_npl_callout rpa_timer;
};

/* NRPA bit: Enables NRPA as private address. */
static bool nrpa_pvcy;

/*** APIs for Peer Device Records.
*
* These Peer records are necessary to take care of Peers with RPA address when
Expand Down Expand Up @@ -305,6 +308,10 @@ is_ble_hs_resolv_enabled(void)
bool
ble_host_rpa_enabled(void)
{
if (nrpa_pvcy) {
return false;
}

if (is_ble_hs_resolv_enabled() && ble_hs_pvcy_enabled()) {
return true;
}
Expand Down Expand Up @@ -385,12 +392,16 @@ ble_hs_resolv_gen_priv_addr(struct ble_hs_resolv_entry *rl, int local)
addr[2] = ecb.cipher_text[13];
}

/* Called to generate RPA address and this address is set in controller as
* Random address. This is necessary in Host based privacy because controller is unaware of RPA
* address is being used */
/* Called to generate private (RPA/NRPA) address and this address is set in controller as
* Random address. This is necessary in Host based privacy because controller
* is unaware of private address is being used */
int
ble_hs_gen_own_rpa_random(void)
ble_hs_gen_own_private_rnd(void)
{
if (nrpa_pvcy) {
return ble_hs_id_set_nrpa_rnd();
}

struct ble_hs_resolv_entry *rl = &g_ble_hs_resolv_list[0];

ble_hs_resolv_gen_priv_addr(rl, 1);
Expand All @@ -412,12 +423,11 @@ ble_hs_get_rpa_local(void)
static void
ble_hs_resolv_rpa_timer_cb(struct ble_npl_event *ev)
{
if (ble_host_rpa_enabled()) {
BLE_HS_LOG(DEBUG, "RPA Timeout; start active adv & scan with new RPA\n");

if (ble_host_rpa_enabled() || (nrpa_pvcy)) {
BLE_HS_LOG(DEBUG, "RPA/NRPA Timeout; start active adv & scan with new Private address \n");
ble_gap_preempt();
/* Generate local RPA */
ble_hs_gen_own_rpa_random();
/* Generate local private address */
ble_hs_gen_own_private_rnd();
ble_npl_callout_reset(&g_ble_hs_resolv_data.rpa_timer,
(int32_t)g_ble_hs_resolv_data.rpa_tmo);
ble_gap_preempt_done();
Expand Down Expand Up @@ -595,6 +605,23 @@ ble_hs_resolv_list_clear_all(void)
return;
}

/**
* Called by host stack to enable NRPA privacy flag for future reference
*/
void
ble_hs_resolv_nrpa_enable(void)
{
nrpa_pvcy = true;
}

/**
* Called by host stack to disable NRPA privacy flag
*/
void
ble_hs_resolv_nrpa_disable(void)
{
nrpa_pvcy = false;
}
/**
* Called to enable or disable address resolution in the host
*
Expand Down
4 changes: 3 additions & 1 deletion nimble/host/src/ble_hs_resolv_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ struct ble_hs_dev_records {

/* Add a device to the resolving list */
int ble_hs_resolv_list_add(uint8_t *cmdbuf);
int ble_hs_gen_own_rpa_random(void);
int ble_hs_gen_own_private_rnd(void);
uint8_t *ble_hs_get_rpa_local(void);

/* Remove a device from the resolving list */
Expand All @@ -71,6 +71,8 @@ void ble_hs_resolv_list_clear_all(void);

/* Address resolution enable command */
void ble_hs_resolv_enable(bool);
void ble_hs_resolv_nrpa_enable(void);
void ble_hs_resolv_nrpa_disable(void);

/* Finds 'addr' in resolving list. Doesnt check if address resolution enabled */
struct ble_hs_resolv_entry *
Expand Down

0 comments on commit 7f59d1f

Please sign in to comment.