Repository: incubator-mynewt-core Updated Branches: refs/heads/develop 8b9c08139 -> 8c891bed0
ensure that we do security pairing with the correct address type and address for our device and theirs. The security legacy pairing algorithm uses 1-bit address type but the new enhanced connection command uses 2 bit address types. This code serves to map between them for pairing. With this code I tested public addr adv and connect to iphone and then pair random addr adv and connect to iphone and then pair rpa adv and connect to iphone and then pair In all cases, I re-advertised and ensure that I coud reconnect (except random) Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/8c891bed Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/8c891bed Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/8c891bed Branch: refs/heads/develop Commit: 8c891bed0850b84665722c58a0ced8da491ef6c7 Parents: 8b9c081 Author: Paul Dietrich <paulfdietr...@yahoo.com> Authored: Fri Jun 3 14:09:27 2016 -0700 Committer: Paul Dietrich <paulfdietr...@yahoo.com> Committed: Fri Jun 3 14:09:27 2016 -0700 ---------------------------------------------------------------------- net/nimble/host/src/ble_gap.c | 7 +++++ net/nimble/host/src/ble_hs_conn_priv.h | 2 ++ net/nimble/host/src/ble_hs_priv.c | 11 +++++++- net/nimble/host/src/ble_hs_priv.h | 1 + net/nimble/host/src/ble_l2cap_sm.c | 44 ++++++++++++++++++++++++++--- 5 files changed, 60 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8c891bed/net/nimble/host/src/ble_gap.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_gap.c b/net/nimble/host/src/ble_gap.c index 4ec25d4..fc12d79 100644 --- a/net/nimble/host/src/ble_gap.c +++ b/net/nimble/host/src/ble_gap.c @@ -110,6 +110,7 @@ static bssnz_t struct { void *cb_arg; unsigned using_wl:1; + unsigned our_addr_type:2; } conn; struct { @@ -129,6 +130,7 @@ static bssnz_t struct { uint8_t conn_mode; uint8_t disc_mode; + unsigned our_addr_type:2; ble_gap_event_fn *cb; void *cb_arg; @@ -896,17 +898,20 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt) conn->bhc_handle = evt->connection_handle; memcpy(conn->bhc_addr, evt->peer_addr, sizeof conn->bhc_addr); conn->bhc_addr_type = evt->peer_addr_type; + memcpy(conn->our_rpa_addr, evt->local_rpa, sizeof(conn->our_rpa_addr)); conn->bhc_itvl = evt->conn_itvl; conn->bhc_latency = evt->conn_latency; conn->bhc_supervision_timeout = evt->supervision_timeout; if (evt->role == BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER) { conn->bhc_flags |= BLE_HS_CONN_F_MASTER; conn->bhc_cb = ble_gap_master.conn.cb; + conn->our_addr_type = ble_gap_master.conn.our_addr_type; conn->bhc_cb_arg = ble_gap_master.conn.cb_arg; ble_gap_master.op = BLE_GAP_OP_NULL; } else { conn->bhc_cb = ble_gap_slave.cb; conn->bhc_cb_arg = ble_gap_slave.cb_arg; + conn->our_addr_type = ble_gap_slave.our_addr_type; ble_gap_slave.op = BLE_GAP_OP_NULL; } @@ -1420,6 +1425,7 @@ ble_gap_adv_start(uint8_t discoverable_mode, uint8_t connectable_mode, ble_gap_slave.cb_arg = cb_arg; ble_gap_slave.conn_mode = connectable_mode; ble_gap_slave.disc_mode = discoverable_mode; + ble_gap_slave.our_addr_type = gap_adv_params.own_addr_type; ble_gap_adv_itvls(discoverable_mode, connectable_mode, &gap_adv_params.adv_itvl_min, @@ -1806,6 +1812,7 @@ ble_gap_conn_initiate(int addr_type, uint8_t *addr, ble_gap_master.conn.cb = cb; ble_gap_master.conn.cb_arg = cb_arg; ble_gap_master.conn.using_wl = addr_type == BLE_GAP_ADDR_TYPE_WL; + ble_gap_master.conn.our_addr_type = params->our_addr_type; rc = ble_gap_conn_create_tx(addr_type, addr, params); if (rc != 0) { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8c891bed/net/nimble/host/src/ble_hs_conn_priv.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs_conn_priv.h b/net/nimble/host/src/ble_hs_conn_priv.h index a77428e..90c32e5 100644 --- a/net/nimble/host/src/ble_hs_conn_priv.h +++ b/net/nimble/host/src/ble_hs_conn_priv.h @@ -37,7 +37,9 @@ struct ble_hs_conn { SLIST_ENTRY(ble_hs_conn) bhc_next; uint16_t bhc_handle; uint8_t bhc_addr_type; + uint8_t our_addr_type; uint8_t bhc_addr[6]; + uint8_t our_rpa_addr[6]; uint16_t bhc_itvl; uint16_t bhc_latency; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8c891bed/net/nimble/host/src/ble_hs_priv.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs_priv.c b/net/nimble/host/src/ble_hs_priv.c index 75d210b..b5720d1 100644 --- a/net/nimble/host/src/ble_hs_priv.c +++ b/net/nimble/host/src/ble_hs_priv.c @@ -25,6 +25,8 @@ int identity_initalized; static uint8_t identity_addr[6]; static uint8_t identity_addr_type; +static uint8_t nrpa[6]; + uint8_t g_irk[16]; @@ -43,15 +45,22 @@ ble_hs_generate_static_random_addr(uint8_t *addr) { return rc; } -int ble_hs_priv_set_nrpa(void) { +int +ble_hs_priv_set_nrpa(void) { int rc; uint8_t addr[6]; rc = ble_hci_util_rand(addr, 6); assert(rc == 0); addr[5] &= ~(0xc0); + memcpy(nrpa, addr, 6); return ble_hs_util_set_random_addr(addr); } +void ble_hs_priv_get_nrpa(uint8_t *addr) { + memcpy(addr,nrpa, 6); +} + + int ble_hs_priv_get_identity_addr_type(uint8_t *addr_type) { if(identity_initalized) { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8c891bed/net/nimble/host/src/ble_hs_priv.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs_priv.h b/net/nimble/host/src/ble_hs_priv.h index fd9247a..71ac8fa 100644 --- a/net/nimble/host/src/ble_hs_priv.h +++ b/net/nimble/host/src/ble_hs_priv.h @@ -104,6 +104,7 @@ int ble_hci_cmd_tx_empty_ack(void *cmd); void ble_hci_cmd_rx_ack(uint8_t *ack_ev); void ble_hci_cmd_init(void); int ble_hs_priv_set_nrpa(void); +void ble_hs_priv_get_nrpa(uint8_t *addr); void ble_hs_priv_update_identity(uint8_t *addr); void ble_hs_priv_update_irk(uint8_t *irk); void bls_hs_priv_copy_local_identity_addr(uint8_t *pdst, uint8_t* addr_type); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8c891bed/net/nimble/host/src/ble_l2cap_sm.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_l2cap_sm.c b/net/nimble/host/src/ble_l2cap_sm.c index dd944f6..fa9e2e3 100644 --- a/net/nimble/host/src/ble_l2cap_sm.c +++ b/net/nimble/host/src/ble_l2cap_sm.c @@ -971,18 +971,54 @@ ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc, uint8_t *ia, uint8_t *ra) { struct ble_hs_conn *conn; + uint8_t our_addr[6]; + uint8_t our_addr_type; BLE_HS_DBG_ASSERT(ble_hs_thread_safe()); conn = ble_hs_conn_find(proc->conn_handle); if (conn != NULL) { + + /* this is tricky because the address we use here for our sec + * calcs depends on the type used in the connection . NOTE + * The security algorithm uses 1-bit iat and rat */ + our_addr_type = conn->our_addr_type; + switch(conn->our_addr_type) { + case BLE_ADDR_TYPE_PUBLIC: + bls_hs_priv_copy_local_identity_addr(our_addr, NULL); + break; + case BLE_ADDR_TYPE_RANDOM: + ble_hs_priv_get_nrpa(our_addr); + break; + case BLE_ADDR_TYPE_RPA_PUB_DEFAULT: + bls_hs_priv_copy_local_identity_addr(our_addr, NULL); + if(memcmp(our_addr, conn->our_rpa_addr, 6) == 0) { + our_addr_type = 0; + } else { + memcpy(our_addr, conn->our_rpa_addr, sizeof(our_addr)); + our_addr_type = 1; + } + break; + case BLE_ADDR_TYPE_RPA_RND_DEFAULT: + ble_hs_priv_get_nrpa(our_addr); + if(memcmp(our_addr, conn->our_rpa_addr, 6) == 0) { + our_addr_type = 1; + } else { + memcpy(our_addr, conn->our_rpa_addr, sizeof(our_addr)); + our_addr_type = 1; + } + break; + } + if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) { - bls_hs_priv_copy_local_identity_addr(ia, iat); - *rat = conn->bhc_addr_type; + memcpy(ia, our_addr, 6); + *iat = our_addr_type; + *rat = (conn->bhc_addr_type ? 1 : 0); memcpy(ra, conn->bhc_addr, 6); } else { - bls_hs_priv_copy_local_identity_addr(ra, rat); - *iat = conn->bhc_addr_type; + memcpy(ra, our_addr, 6); + *rat = our_addr_type; + *iat = (conn->bhc_addr_type ? 1 : 0); memcpy(ia, conn->bhc_addr, 6); } }