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/06/06 14:30:21 UTC
[13/13] incubator-mynewt-core git commit: BLE Host - Encryption key
refresh.
BLE Host - Encryption key refresh.
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/60a7b59b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/60a7b59b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/60a7b59b
Branch: refs/heads/upf54
Commit: 60a7b59b1c386cdaf2d56cce9698911aaeec6b38
Parents: c838b9f
Author: Christopher Collins <cc...@apache.org>
Authored: Mon Jun 6 22:29:39 2016 +0800
Committer: Christopher Collins <cc...@apache.org>
Committed: Mon Jun 6 22:29:39 2016 +0800
----------------------------------------------------------------------
net/nimble/host/src/ble_sm.c | 78 +++++++++++++++++++++++++----
net/nimble/host/src/ble_sm_priv.h | 4 ++
net/nimble/host/src/host_hci.c | 19 +++++++
net/nimble/include/nimble/hci_common.h | 9 ++++
4 files changed, 99 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/60a7b59b/net/nimble/host/src/ble_sm.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_sm.c b/net/nimble/host/src/ble_sm.c
index 6f47967..72c891c 100644
--- a/net/nimble/host/src/ble_sm.c
+++ b/net/nimble/host/src/ble_sm.c
@@ -52,7 +52,9 @@
#if NIMBLE_OPT(SM)
/** Procedure timeout; 30 seconds. */
-#define BLE_SM_TIMEOUT_OS_TICKS (30 * OS_TICKS_PER_SEC)
+#define BLE_SM_TIMEOUT_OS_TICKS (30 * OS_TICKS_PER_SEC)
+
+#define BLE_SM_ENC_STATE_NO_CHANGE (-1)
STAILQ_HEAD(ble_sm_proc_list, ble_sm_proc);
@@ -573,11 +575,11 @@ ble_sm_persist_keys(struct ble_sm_proc *proc)
}
static void
-ble_sm_enc_event(struct ble_sm_proc *proc, int status, int enc_enabled)
+ble_sm_enc_event(struct ble_sm_proc *proc, int status, int enc_state)
{
struct ble_gap_sec_state sec_state;
- ble_sm_sec_state(proc, &sec_state, enc_enabled);
+ ble_sm_sec_state(proc, &sec_state, enc_state);
ble_gap_enc_event(proc->conn_handle, status, &sec_state);
}
@@ -782,6 +784,7 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res)
{
struct ble_sm_proc *prev;
struct ble_sm_proc *proc;
+ struct ble_hs_conn *conn;
int rm;
rm = 0;
@@ -809,6 +812,15 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res)
} else {
ble_sm_proc_set_timer(proc);
}
+
+ if (res->enc_cb && res->enc_state == BLE_SM_ENC_STATE_NO_CHANGE) {
+ conn = ble_hs_conn_find(conn_handle);
+ if (conn != NULL) {
+ res->enc_state = conn->bhc_sec_state.enc_enabled;
+ } else {
+ res->enc_state = 0;
+ }
+ }
}
if (res->sm_err != 0) {
@@ -823,7 +835,7 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res)
if (res->enc_cb) {
BLE_HS_DBG_ASSERT(rm);
- ble_sm_enc_event(proc, res->app_status, res->app_status == 0);
+ ble_sm_enc_event(proc, res->app_status, res->enc_state);
}
if (res->app_status == 0 &&
@@ -926,23 +938,21 @@ ble_sm_enc_change_rx(struct hci_encrypt_change *evt)
{
struct ble_sm_result res;
struct ble_sm_proc *proc;
- struct ble_sm_proc *prev;
- int enc_enabled = 0;
int do_key_exchange = 0;
memset(&res, 0, sizeof res);
ble_hs_lock();
proc = ble_sm_proc_find(evt->connection_handle, BLE_SM_PROC_STATE_NONE, -1,
- &prev);
+ NULL);
if (proc == NULL) {
res.app_status = BLE_HS_ENOENT;
} else if (proc->state == BLE_SM_PROC_STATE_ENC_START) {
- enc_enabled = evt->encryption_enabled & 0x01; /* LE bit. */
+ res.enc_state = evt->encryption_enabled & 0x01; /* LE bit. */
do_key_exchange = proc->flags & BLE_SM_PROC_F_KEY_EXCHANGE;
res.app_status = 0;
} else if (proc->state == BLE_SM_PROC_STATE_ENC_RESTORE) {
- enc_enabled = evt->encryption_enabled & 0x01; /* LE bit. */
+ res.enc_state = evt->encryption_enabled & 0x01; /* LE bit. */
do_key_exchange = 0;
res.app_status = 0;
} else {
@@ -950,8 +960,54 @@ ble_sm_enc_change_rx(struct hci_encrypt_change *evt)
res.app_status = BLE_HS_ENOENT;
}
- if (res.app_status == 0 && enc_enabled) {
- if (do_key_exchange) {
+ if (res.app_status == 0) {
+ if (evt->status != 0) {
+ res.app_status = BLE_HS_HCI_ERR(evt->status);
+ res.enc_cb = 1;
+ } else {
+ if (res.enc_state == 1 && do_key_exchange) {
+ proc->state = BLE_SM_PROC_STATE_KEY_EXCH;
+
+ /* The responder sends its keys first. */
+ if (!(proc->flags & BLE_SM_PROC_F_INITIATOR)) {
+ res.execute = 1;
+ }
+ } else {
+ proc->state = BLE_SM_PROC_STATE_NONE;
+ res.enc_cb = 1;
+ }
+ }
+ }
+
+ ble_hs_unlock();
+
+ ble_sm_process_result(evt->connection_handle, &res);
+}
+
+void
+ble_sm_enc_key_refresh_rx(struct hci_encrypt_key_refresh *evt)
+{
+ struct ble_sm_result res;
+ struct ble_sm_proc *proc;
+ int do_key_exchange;
+
+ ble_hs_lock();
+ proc = ble_sm_proc_find(evt->connection_handle,
+ BLE_SM_PROC_STATE_ENC_START, -1, NULL);
+ if (proc == NULL) {
+ res.app_status = BLE_HS_ENOENT;
+ do_key_exchange = 0;
+ } else {
+ res.app_status = 0;
+ do_key_exchange = proc->flags & BLE_SM_PROC_F_KEY_EXCHANGE;
+ }
+
+ if (res.app_status == 0) {
+ res.enc_state = BLE_SM_ENC_STATE_NO_CHANGE;
+ if (evt->status != 0) {
+ res.app_status = BLE_HS_HCI_ERR(evt->status);
+ res.enc_cb = 1;
+ } else if (do_key_exchange) {
proc->state = BLE_SM_PROC_STATE_KEY_EXCH;
/* The responder sends its keys first. */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/60a7b59b/net/nimble/host/src/ble_sm_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_sm_priv.h b/net/nimble/host/src/ble_sm_priv.h
index b4554df..18f6a1c 100644
--- a/net/nimble/host/src/ble_sm_priv.h
+++ b/net/nimble/host/src/ble_sm_priv.h
@@ -286,6 +286,9 @@ struct ble_sm_result {
unsigned execute:1;
unsigned enc_cb:1;
unsigned persist_keys:1;
+
+ /* 0=disabled; 1=enabled; -1=no-change. */
+ uint8_t enc_state;
};
#ifdef BLE_HS_DEBUG
@@ -390,6 +393,7 @@ int ble_sm_alg_gen_dhkey(uint8_t *peer_pub_key_x, uint8_t *peer_pub_key_y,
int ble_sm_alg_gen_key_pair(void *pub, uint32_t *priv);
void ble_sm_enc_change_rx(struct hci_encrypt_change *evt);
+void ble_sm_enc_key_refresh_rx(struct hci_encrypt_key_refresh *evt);
int ble_sm_ltk_req_rx(struct hci_le_lt_key_req *evt);
int ble_sm_lgcy_io_action(struct ble_sm_proc *proc);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/60a7b59b/net/nimble/host/src/host_hci.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_hci.c b/net/nimble/host/src/host_hci.c
index e75e22c..5f58663 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -35,6 +35,7 @@ typedef int host_hci_event_fn(uint8_t event_code, uint8_t *data, int len);
static host_hci_event_fn host_hci_rx_disconn_complete;
static host_hci_event_fn host_hci_rx_encrypt_change;
static host_hci_event_fn host_hci_rx_num_completed_pkts;
+static host_hci_event_fn host_hci_rx_enc_key_refresh;
static host_hci_event_fn host_hci_rx_le_meta;
typedef int host_hci_le_event_fn(uint8_t subevent, uint8_t *data, int len);
@@ -68,6 +69,7 @@ static const struct host_hci_event_dispatch_entry host_hci_event_dispatch[] = {
{ BLE_HCI_EVCODE_DISCONN_CMP, host_hci_rx_disconn_complete },
{ BLE_HCI_EVCODE_ENCRYPT_CHG, host_hci_rx_encrypt_change },
{ BLE_HCI_EVCODE_NUM_COMP_PKTS, host_hci_rx_num_completed_pkts },
+ { BLE_HCI_EVCODE_ENC_KEY_REFRESH, host_hci_rx_enc_key_refresh },
{ BLE_HCI_EVCODE_LE_META, host_hci_rx_le_meta },
};
@@ -180,6 +182,23 @@ host_hci_rx_encrypt_change(uint8_t event_code, uint8_t *data, int len)
}
static int
+host_hci_rx_enc_key_refresh(uint8_t event_code, uint8_t *data, int len)
+{
+ struct hci_encrypt_key_refresh evt;
+
+ if (len < BLE_HCI_EVENT_ENC_KEY_REFRESH_LEN) {
+ return BLE_HS_ECONTROLLER;
+ }
+
+ evt.status = data[2];
+ evt.connection_handle = le16toh(data + 3);
+
+ ble_sm_enc_key_refresh_rx(&evt);
+
+ return 0;
+}
+
+static int
host_hci_rx_num_completed_pkts(uint8_t event_code, uint8_t *data, int len)
{
uint16_t num_pkts;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/60a7b59b/net/nimble/include/nimble/hci_common.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/hci_common.h b/net/nimble/include/nimble/hci_common.h
index ea19cdd..280f65a 100644
--- a/net/nimble/include/nimble/hci_common.h
+++ b/net/nimble/include/nimble/hci_common.h
@@ -465,6 +465,8 @@
/* Event encryption change (code=0x08) */
#define BLE_HCI_EVENT_ENCRYPT_CHG_LEN (4)
+
+/* Event key refresh complete (code=0x30) */
#define BLE_HCI_EVENT_ENC_KEY_REFRESH_LEN (3)
/* Event command complete */
@@ -644,6 +646,13 @@ struct hci_encrypt_change
uint16_t connection_handle;
};
+/* Encryption key refresh complete event (code=0x30) */
+struct hci_encrypt_key_refresh
+{
+ uint8_t status;
+ uint16_t connection_handle;
+};
+
/* Connection complete LE meta subevent */
struct hci_le_conn_complete
{