From dbdea0fb33c03969334a2d5f6b81bbe2ede330e2 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 12 Feb 2018 20:46:47 +0100 Subject: [PATCH] nimble/ll: Use NRPA for scan requests to unknown devices With privacy enabled, we'll use NRPA instead of identity address to send scan requests to devices which are not on our resolving list. This is to prevent us from being tracked when doing active scanning. X-Original-Commit: 0cde652d1eef0b7f7ef202e7418284e675687cfa --- .../include/controller/ble_ll_scan.h | 4 +++ nimble/controller/src/ble_ll_scan.c | 36 ++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index 8a4cee537..35cbeb44a 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -119,6 +119,10 @@ struct ble_ll_scan_sm uint8_t scan_rsp_cons_ok; int8_t scan_rpa_index; uint8_t scan_peer_rpa[BLE_DEV_ADDR_LEN]; +#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1) + uint32_t scan_nrpa_timer; + uint8_t scan_nrpa[BLE_DEV_ADDR_LEN]; +#endif /* XXX: Shall we count backoff per phy? */ uint16_t upper_limit; diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 5aa984b9c..b20cbfc99 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -263,6 +263,24 @@ ble_ll_scan_req_backoff(struct ble_ll_scan_sm *scansm, int success) assert(scansm->backoff_count <= 256); } +#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1) +static void +ble_ll_scan_refresh_nrpa(struct ble_ll_scan_sm *scansm) +{ + uint32_t now; + + now = os_time_get(); + if ((int32_t)(now - scansm->scan_nrpa_timer) >= 0) { + /* Generate new NRPA */ + ble_ll_rand_data_get(scansm->scan_nrpa, BLE_DEV_ADDR_LEN); + scansm->scan_nrpa[5] &= ~0xc0; + + /* We'll use the same timeout as for RPA rotation */ + scansm->scan_nrpa_timer = now + ble_ll_resolv_get_rpa_tmo(); + } +} +#endif + /** * ble ll scan req pdu make * @@ -318,11 +336,22 @@ ble_ll_scan_req_pdu_make(struct ble_ll_scan_sm *scansm, uint8_t *adv_addr, } } + /* + * If advertising device is on our resolving list, we use RPA generated + * using Local IRK from resolving list entry as ScanA. In other case, + * we use NRPA as ScanA as allowed by spec to prevent our device from + * being tracked when doing an active scan (see Core 5.0, Vol 6, Part B, + * section 6.3). + */ if (rl) { ble_ll_resolv_gen_priv_addr(rl, 1, rpa); scana = rpa; - pdu_type |= BLE_ADV_PDU_HDR_TXADD_RAND; + } else { + ble_ll_scan_refresh_nrpa(scansm); + scana = scansm->scan_nrpa; } + + pdu_type |= BLE_ADV_PDU_HDR_TXADD_RAND; } #endif @@ -3044,6 +3073,11 @@ ble_ll_scan_init(void) scansm->phy_data[PHY_CODED].phy = BLE_PHY_CODED; #endif +#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1) + /* Make sure we'll generate new NRPA if necessary */ + scansm->scan_nrpa_timer = os_time_get(); +#endif + /* Initialize scanning timer */ os_cputime_timer_init(&scansm->scan_timer, ble_ll_scan_timer_cb, scansm);