mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-07-30 06:37:55 +00:00
NimBLE host: Add Non-Resolvable Private address support
- Add NRPA support to existing Host based Privacy framework
This commit is contained in:
committed by
Abhinav Kudnar
parent
9fd99b3917
commit
7f59d1fe16
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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 *
|
||||
|
||||
Reference in New Issue
Block a user