You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2016/05/25 19:17:00 UTC
[7/9] incubator-mynewt-core git commit: BLE Host - Add peer address
to ltk store.
BLE Host - Add peer address to ltk store.
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/7b6fcb93
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/7b6fcb93
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/7b6fcb93
Branch: refs/heads/develop
Commit: 7b6fcb93922587c40480eb492a15d9421d830958
Parents: 23fda23
Author: Christopher Collins <cc...@apache.org>
Authored: Wed May 25 09:36:17 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed May 25 12:16:46 2016 -0700
----------------------------------------------------------------------
net/nimble/host/include/host/ble_store.h | 20 +++++
net/nimble/host/src/ble_att_svr.c | 23 ++---
net/nimble/host/src/ble_l2cap_sm.c | 90 +++++++++++++-------
net/nimble/host/src/ble_store.c | 20 +++++
.../host/src/test/ble_hs_test_util_store.c | 37 +++++---
net/nimble/host/src/test/ble_l2cap_sm_test.c | 1 +
6 files changed, 139 insertions(+), 52 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7b6fcb93/net/nimble/host/include/host/ble_store.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_store.h b/net/nimble/host/include/host/ble_store.h
index 5d54ce9..08bcb9e 100644
--- a/net/nimble/host/include/host/ble_store.h
+++ b/net/nimble/host/include/host/ble_store.h
@@ -27,17 +27,35 @@
#define BLE_STORE_OBJ_TYPE_CCCD 3
#define BLE_STORE_PEER_ADDR_TYPE_NONE 0xff
+#define BLE_STORE_AUTHREQ_NONE 0xff
struct ble_store_key_ltk {
+ /**
+ * Key by peer identity address;
+ * peer_addr_type=BLE_STORE_PEER_ADDR_TYPE_NONE means don't key off peer.
+ */
+ uint8_t addr[6];
+ uint8_t addr_type;
+
+ /** Key by ediv; ediv_present=0 means don't key off ediv. */
uint16_t ediv;
+ unsigned ediv_present:1;
+
+ /** Key by rand_num; rand_num_present=0 means don't key off rand_num. */
uint64_t rand_num;
+ unsigned rand_num_present:1;
};
struct ble_store_value_ltk {
+ uint8_t addr[6];
+ uint8_t addr_type;
uint16_t ediv;
uint64_t rand_num;
uint8_t key[16];
+
unsigned authenticated:1;
+ unsigned sc:1;
+
};
struct ble_store_key_cccd {
@@ -88,6 +106,8 @@ int ble_store_read(int obj_type, union ble_store_key *key,
int ble_store_write(int obj_type, union ble_store_value *val);
int ble_store_delete(int obj_type, union ble_store_key *key);
+int ble_store_read_peer_ltk(struct ble_store_key_ltk *key_ltk,
+ struct ble_store_value_ltk *value_ltk);
int ble_store_read_cccd(struct ble_store_key_cccd *key,
struct ble_store_value_cccd *out_value);
int ble_store_write_cccd(struct ble_store_value_cccd *value);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7b6fcb93/net/nimble/host/src/ble_att_svr.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_svr.c b/net/nimble/host/src/ble_att_svr.c
index 47e4418..49238ac 100644
--- a/net/nimble/host/src/ble_att_svr.c
+++ b/net/nimble/host/src/ble_att_svr.c
@@ -357,17 +357,20 @@ ble_att_svr_write(uint16_t conn_handle, struct ble_att_svr_entry *entry,
BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
- if (conn_handle != BLE_HS_CONN_HANDLE_NONE &&
- !(entry->ha_flags & BLE_ATT_F_WRITE)) {
-
- att_err = BLE_ATT_ERR_WRITE_NOT_PERMITTED;
- rc = BLE_HS_ENOTSUP;
- goto err;
- }
+ /* Bypass permissions and security checks if we are writing our own
+ * attribute.
+ */
+ if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
+ if (!(entry->ha_flags & BLE_ATT_F_WRITE)) {
+ att_err = BLE_ATT_ERR_WRITE_NOT_PERMITTED;
+ rc = BLE_HS_ENOTSUP;
+ goto err;
+ }
- rc = ble_att_svr_check_security(conn_handle, 0, entry, &att_err);
- if (rc != 0) {
- goto err;
+ rc = ble_att_svr_check_security(conn_handle, 0, entry, &att_err);
+ if (rc != 0) {
+ goto err;
+ }
}
BLE_HS_DBG_ASSERT(entry->ha_cb != NULL);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7b6fcb93/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 5f20c18..e9d5230 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -490,6 +490,7 @@ ble_l2cap_sm_key_exchange_events(struct ble_l2cap_sm_proc *proc)
sizeof store_value.ltk.key);
store_value.ltk.authenticated =
!!(proc->flags & BLE_L2CAP_SM_PROC_F_AUTHENTICATED);
+ store_value.ltk.sc = 0;
ble_store_write(BLE_STORE_OBJ_TYPE_OUR_LTK, &store_value);
}
@@ -500,6 +501,7 @@ ble_l2cap_sm_key_exchange_events(struct ble_l2cap_sm_proc *proc)
sizeof store_value.ltk.key);
store_value.ltk.authenticated =
!!(proc->flags & BLE_L2CAP_SM_PROC_F_AUTHENTICATED);
+ store_value.ltk.sc = 0;
ble_store_write(BLE_STORE_OBJ_TYPE_PEER_LTK, &store_value);
}
@@ -1763,16 +1765,20 @@ ble_l2cap_sm_lt_key_req_ltk_handle(struct hci_le_lt_key_req *evt)
union ble_store_key store_key;
struct ble_l2cap_sm_proc *proc;
struct ble_l2cap_sm_proc *prev;
- int app_rc;
+ int store_rc;
int rc;
/* Tell applicaiton to look up LTK by ediv/rand pair. */
+ /* XXX: Also filter by peer address? */
+ memset(&store_key, 0, sizeof store_key);
store_key.ltk.ediv = evt->encrypted_diversifier;
+ store_key.ltk.ediv_present = 1;
store_key.ltk.rand_num = evt->random_number;
- app_rc = ble_store_read(BLE_STORE_OBJ_TYPE_OUR_LTK, &store_key,
- &store_value);
- if (app_rc == 0) {
- /* App provided a key; send it to the controller. */
+ store_key.ltk.rand_num_present = 1;
+ store_rc = ble_store_read(BLE_STORE_OBJ_TYPE_OUR_LTK, &store_key,
+ &store_value);
+ if (store_rc == 0) {
+ /* Store provided a key; send it to the controller. */
rc = ble_l2cap_sm_lt_key_req_reply_tx(evt->connection_handle,
store_value.ltk.key);
} else {
@@ -1788,7 +1794,7 @@ ble_l2cap_sm_lt_key_req_ltk_handle(struct hci_le_lt_key_req *evt)
&prev);
if (proc == NULL) {
rc = BLE_HS_EUNKNOWN;
- } else if (app_rc == 0 && rc == 0) {
+ } else if (store_rc == 0 && rc == 0) {
proc->state = BLE_L2CAP_SM_PROC_STATE_ENC_CHANGE;
if (store_value.ltk.authenticated) {
proc->flags |= BLE_L2CAP_SM_PROC_F_AUTHENTICATED;
@@ -1799,14 +1805,14 @@ ble_l2cap_sm_lt_key_req_ltk_handle(struct hci_le_lt_key_req *evt)
ble_hs_unlock();
/* Notify the app if it provided a key and the procedure failed. */
- if (app_rc == 0 && rc != 0) {
+ if (store_rc == 0 && rc != 0) {
ble_l2cap_sm_gap_event(proc, rc, 0);
}
/* The procedure is aborted if the app didn't provide a key or if there was
* a failure.
*/
- if (app_rc != 0 || rc != 0) {
+ if (store_rc != 0 || rc != 0) {
ble_l2cap_sm_proc_free(proc);
}
@@ -1928,8 +1934,10 @@ static int
ble_l2cap_sm_rx_sec_req(uint16_t conn_handle, uint8_t op, struct os_mbuf **om)
{
struct ble_l2cap_sm_sec_req cmd;
- struct ble_l2cap_sm_proc *proc;
+ struct ble_store_value_ltk value_ltk;
+ struct ble_store_key_ltk key_ltk;
struct ble_hs_conn *conn;
+ int authreq_mitm;
int rc;
rc = ble_hs_misc_pullup_base(om, BLE_L2CAP_SM_SEC_REQ_SZ);
@@ -1939,39 +1947,57 @@ ble_l2cap_sm_rx_sec_req(uint16_t conn_handle, uint8_t op, struct os_mbuf **om)
ble_l2cap_sm_sec_req_parse((*om)->om_data, (*om)->om_len, &cmd);
+ /* XXX: Reject if:
+ * o authreq-bonded flag not set?
+ * o authreq-reserved flags set?
+ */
+
BLE_HS_LOG(DEBUG, "rxed sm sec req; authreq=%d\n", cmd.authreq);
ble_hs_lock();
- /* Only handle the security request if a procedure isn't already in
- * progress for this connection.
- */
- proc = ble_l2cap_sm_proc_find(conn_handle, BLE_L2CAP_SM_PROC_STATE_NONE,
- -1, NULL);
- if (proc != NULL) {
- rc = BLE_HS_EALREADY;
+ conn = ble_hs_conn_find(conn_handle);
+ if (conn == NULL) {
+ rc = BLE_HS_ENOTCONN;
+ } else if (!(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) {
+ rc = BLE_HS_SM_US_ERR(BLE_L2CAP_SM_ERR_CMD_NOT_SUPP);
+ ble_l2cap_sm_pair_fail_tx(conn_handle, BLE_L2CAP_SM_ERR_CMD_NOT_SUPP);
} else {
- conn = ble_hs_conn_find(conn_handle);
- if (conn == NULL) {
- rc = BLE_HS_ENOTCONN;
- } else if (!(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) {
- rc = BLE_HS_SM_US_ERR(BLE_L2CAP_SM_ERR_CMD_NOT_SUPP);
- ble_l2cap_sm_pair_fail_tx(conn_handle,
- BLE_L2CAP_SM_ERR_CMD_NOT_SUPP);
- } else {
- rc = 0;
- }
+ rc = 0;
+
+ /* We will be querying the SM database for a key corresponding to the
+ * sender; remember the sender's address while the connection list is
+ * locked.
+ */
+ memset(&key_ltk, 0, sizeof key_ltk);
+ key_ltk.addr_type = conn->bhc_addr_type;
+ memcpy(key_ltk.addr, conn->bhc_addr, 6);
}
ble_hs_unlock();
if (rc == 0) {
- /* XXX: Ask app / someone if there is a persisted LTK such that:
- * o It corresponds to this peer.
- * o It meets the specified authreq criteria.
- * For now, assume we don't have an appropriate LTK; initiate pairing.
- */
- rc = ble_l2cap_sm_pair_initiate(conn_handle);
+ /* Query database for an LTK corresonding to the sender. */
+ rc = ble_store_read_peer_ltk(&key_ltk, &value_ltk);
+ if (rc == 0) {
+ /* Found a key corresponding to this peer. Make sure it meets the
+ * requested minimum authreq.
+ */
+ authreq_mitm = cmd.authreq & BLE_L2CAP_SM_PAIR_AUTHREQ_MITM;
+ if ((!authreq_mitm && value_ltk.authenticated) ||
+ (authreq_mitm && !value_ltk.authenticated)) {
+
+ rc = BLE_HS_EREJECT;
+ }
+ }
+
+ if (rc == 0) {
+ rc = ble_l2cap_sm_enc_initiate(conn_handle, value_ltk.key,
+ value_ltk.ediv, value_ltk.rand_num,
+ value_ltk.authenticated);
+ } else {
+ rc = ble_l2cap_sm_pair_initiate(conn_handle);
+ }
}
return rc;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7b6fcb93/net/nimble/host/src/ble_store.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_store.c b/net/nimble/host/src/ble_store.c
index 267e8d3..580f145 100644
--- a/net/nimble/host/src/ble_store.c
+++ b/net/nimble/host/src/ble_store.c
@@ -66,6 +66,20 @@ ble_store_delete(int obj_type, union ble_store_key *key)
}
int
+ble_store_read_peer_ltk(struct ble_store_key_ltk *key_ltk,
+ struct ble_store_value_ltk *value_ltk)
+{
+ union ble_store_value *store_value;
+ union ble_store_key *store_key;
+ int rc;
+
+ store_key = (void *)key_ltk;
+ store_value = (void *)value_ltk;
+ rc = ble_store_read(BLE_STORE_OBJ_TYPE_PEER_LTK, store_key, store_value);
+ return rc;
+}
+
+int
ble_store_read_cccd(struct ble_store_key_cccd *key,
struct ble_store_value_cccd *out_value)
{
@@ -115,6 +129,12 @@ void
ble_store_key_from_value_ltk(struct ble_store_key_ltk *out_key,
struct ble_store_value_ltk *value)
{
+ out_key->addr_type = value->addr_type;
+ memcpy(out_key->addr, value->addr, sizeof out_key->addr);
+
out_key->ediv = value->ediv;
+ out_key->ediv_present = 1;
+
out_key->rand_num = value->rand_num;
+ out_key->rand_num_present = 1;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7b6fcb93/net/nimble/host/src/test/ble_hs_test_util_store.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test_util_store.c b/net/nimble/host/src/test/ble_hs_test_util_store.c
index 51f6dde..2172ebb 100644
--- a/net/nimble/host/src/test/ble_hs_test_util_store.c
+++ b/net/nimble/host/src/test/ble_hs_test_util_store.c
@@ -86,15 +86,32 @@ ble_hs_test_util_store_read_ltk(struct ble_store_value_ltk *store,
struct ble_store_key_ltk *key,
struct ble_store_value_ltk *value)
{
- struct ble_store_value_ltk *ltk;
+ struct ble_store_value_ltk *cur;
int i;
for (i = 0; i < num_values; i++) {
- ltk = store + i;
- if (ltk->ediv == key->ediv && ltk->rand_num == key->rand_num) {
- *value = *ltk;
- return 0;
+ cur = store + i;
+
+ if (key->addr_type != BLE_STORE_PEER_ADDR_TYPE_NONE) {
+ if (cur->addr_type != key->addr_type) {
+ continue;
+ }
+
+ if (memcmp(cur->addr, key->addr, sizeof cur->addr) != 0) {
+ continue;
+ }
}
+
+ if (key->ediv_present && cur->ediv != key->ediv) {
+ continue;
+ }
+
+ if (key->rand_num_present && cur->rand_num != key->rand_num) {
+ continue;
+ }
+
+ *value = *cur;
+ return 0;
}
return BLE_HS_ENOENT;
@@ -103,26 +120,26 @@ ble_hs_test_util_store_read_ltk(struct ble_store_value_ltk *store,
static int
ble_hs_test_util_store_find_cccd(struct ble_store_key_cccd *key)
{
- struct ble_store_value_cccd *cccd;
+ struct ble_store_value_cccd *cur;
int skipped;
int i;
skipped = 0;
for (i = 0; i < ble_hs_test_util_store_num_cccds; i++) {
- cccd = ble_hs_test_util_store_cccds + i;
+ cur = ble_hs_test_util_store_cccds + i;
if (key->peer_addr_type != BLE_STORE_PEER_ADDR_TYPE_NONE) {
- if (cccd->peer_addr_type != key->peer_addr_type) {
+ if (cur->peer_addr_type != key->peer_addr_type) {
continue;
}
- if (memcmp(cccd->peer_addr, key->peer_addr, 6) != 0) {
+ if (memcmp(cur->peer_addr, key->peer_addr, 6) != 0) {
continue;
}
}
if (key->chr_val_handle != 0) {
- if (cccd->chr_val_handle != key->chr_val_handle) {
+ if (cur->chr_val_handle != key->chr_val_handle) {
continue;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7b6fcb93/net/nimble/host/src/test/ble_l2cap_sm_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_l2cap_sm_test.c b/net/nimble/host/src/test/ble_l2cap_sm_test.c
index c58396d..d955132 100644
--- a/net/nimble/host/src/test/ble_l2cap_sm_test.c
+++ b/net/nimble/host/src/test/ble_l2cap_sm_test.c
@@ -1780,6 +1780,7 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_sec_req_inval)
ble_l2cap_sm_test_util_verify_tx_pair_fail(&fail);
/*** Pairing already in progress; ignore security request. */
+ ble_hs_atomic_conn_set_flags(2, BLE_HS_CONN_F_MASTER, 1);
rc = ble_l2cap_sm_pair_initiate(2);
TEST_ASSERT_FATAL(rc == 0);
ble_hs_test_util_tx_all();