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
 {