NimBLE host: Add Non-Resolvable Private address support

- Add NRPA support to existing Host based Privacy framework
This commit is contained in:
Prasad Alatkar
2024-02-14 15:08:29 +05:30
committed by Abhinav Kudnar
parent 9fd99b3917
commit 7f59d1fe16
6 changed files with 110 additions and 17 deletions
+29 -5
View File
@@ -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.
*
* @param enable RPA when enable is not 0
* disable RPA otherwise
* 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 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
+31
View File
@@ -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
+1
View File
@@ -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
}
+10 -2
View File
@@ -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];
@@ -307,7 +308,7 @@ 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;
@@ -315,8 +316,15 @@ ble_hs_pvcy_rpa_config(uint8_t enable)
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);
}
+36 -9
View File
@@ -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
@@ -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;
}
@@ -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);
@@ -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();
@@ -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
*
+3 -1
View File
@@ -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 */
@@ -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 *