mynewt-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ccoll...@apache.org
Subject incubator-mynewt-core git commit: Some preliminary passkey & OOB.
Date Tue, 29 Mar 2016 00:36:31 GMT
Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop 44cc9fd67 -> 696683c9a


Some preliminary passkey & OOB.


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/696683c9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/696683c9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/696683c9

Branch: refs/heads/develop
Commit: 696683c9af2ded7d741f9d2e26d9716420f58ee9
Parents: 44cc9fd
Author: Christopher Collins <ccollins@apache.org>
Authored: Mon Mar 28 14:15:45 2016 -0700
Committer: Christopher Collins <ccollins@apache.org>
Committed: Mon Mar 28 17:36:05 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_gap.h       |   2 +-
 net/nimble/host/include/host/ble_hs.h        |  75 +++++++------
 net/nimble/host/include/host/ble_l2cap.h     |  28 ++++-
 net/nimble/host/pkg.yml                      |   4 +-
 net/nimble/host/src/ble_gap.c                |  30 +----
 net/nimble/host/src/ble_gap_priv.h           |   5 +-
 net/nimble/host/src/ble_hs_cfg.c             |   8 ++
 net/nimble/host/src/ble_l2cap_sig.c          |   4 +-
 net/nimble/host/src/ble_l2cap_sm.c           | 127 ++++++++++++++++------
 net/nimble/host/src/ble_l2cap_sm.h           |  15 ---
 net/nimble/host/src/test/ble_l2cap_sm_test.c |  62 +++++++++--
 11 files changed, 234 insertions(+), 126 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/include/host/ble_gap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_gap.h b/net/nimble/host/include/host/ble_gap.h
index 872b3ec..c9ad502 100644
--- a/net/nimble/host/include/host/ble_gap.h
+++ b/net/nimble/host/include/host/ble_gap.h
@@ -130,7 +130,7 @@ struct ble_gap_upd_params {
 };
 
 struct ble_gap_sec_params {
-    uint8_t enc_type;
+    uint8_t pair_alg;
     unsigned enc_enabled:1;
     unsigned auth_enabled:1;
 };

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/include/host/ble_hs.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_hs.h b/net/nimble/host/include/host/ble_hs.h
index c532ca0..56c67bb 100644
--- a/net/nimble/host/include/host/ble_hs.h
+++ b/net/nimble/host/include/host/ble_hs.h
@@ -29,38 +29,41 @@
 #include "host/ble_uuid.h"
 #include "host/host_hci.h"
 
-#define BLE_HS_CONN_HANDLE_NONE         0xffff
-
-#define BLE_HS_EAGAIN                   1
-#define BLE_HS_EALREADY                 2
-#define BLE_HS_EINVAL                   3
-#define BLE_HS_EMSGSIZE                 4
-#define BLE_HS_ENOENT                   5
-#define BLE_HS_ENOMEM                   6
-#define BLE_HS_ENOTCONN                 7
-#define BLE_HS_ENOTSUP                  8
-#define BLE_HS_EAPP                     9
-#define BLE_HS_EBADDATA                 10
-#define BLE_HS_EOS                      11
-#define BLE_HS_ECONGESTED               12
-#define BLE_HS_ECONTROLLER              13
-#define BLE_HS_ETIMEOUT                 14
-#define BLE_HS_EDONE                    15
-#define BLE_HS_EBUSY                    16
-#define BLE_HS_EREJECT                  17
-#define BLE_HS_EUNKNOWN                 18
-
-#define BLE_HS_ERR_ATT_BASE             0x100   /* 256 */
-#define BLE_HS_ATT_ERR(x)               ((x) ? BLE_HS_ERR_ATT_BASE + (x) : 0)
-
-#define BLE_HS_ERR_HCI_BASE             0x200   /* 512 */
-#define BLE_HS_HCI_ERR(x)               ((x) ? BLE_HS_ERR_HCI_BASE + (x) : 0)
-
-#define BLE_HS_ERR_L2C_BASE             0x300   /* 768 */
-#define BLE_HS_L2C_ERR(x)               ((x) ? BLE_HS_ERR_L2C_BASE + (x) : 0)
-
-#define BLE_HS_ERR_SM_BASE              0x400   /* 1024 */
-#define BLE_HS_SM_ERR(x)                ((x) ? BLE_HS_ERR_SM_BASE + (x) : 0)
+#define BLE_HS_CONN_HANDLE_NONE     0xffff
+
+#define BLE_HS_EAGAIN               1
+#define BLE_HS_EALREADY             2
+#define BLE_HS_EINVAL               3
+#define BLE_HS_EMSGSIZE             4
+#define BLE_HS_ENOENT               5
+#define BLE_HS_ENOMEM               6
+#define BLE_HS_ENOTCONN             7
+#define BLE_HS_ENOTSUP              8
+#define BLE_HS_EAPP                 9
+#define BLE_HS_EBADDATA             10
+#define BLE_HS_EOS                  11
+#define BLE_HS_ECONGESTED           12
+#define BLE_HS_ECONTROLLER          13
+#define BLE_HS_ETIMEOUT             14
+#define BLE_HS_EDONE                15
+#define BLE_HS_EBUSY                16
+#define BLE_HS_EREJECT              17
+#define BLE_HS_EUNKNOWN             18
+
+#define BLE_HS_ERR_ATT_BASE         0x100   /* 256 */
+#define BLE_HS_ATT_ERR(x)           ((x) ? BLE_HS_ERR_ATT_BASE + (x) : 0)
+
+#define BLE_HS_ERR_HCI_BASE         0x200   /* 512 */
+#define BLE_HS_HCI_ERR(x)           ((x) ? BLE_HS_ERR_HCI_BASE + (x) : 0)
+
+#define BLE_HS_ERR_L2C_BASE         0x300   /* 768 */
+#define BLE_HS_L2C_ERR(x)           ((x) ? BLE_HS_ERR_L2C_BASE + (x) : 0)
+
+#define BLE_HS_ERR_SM_US_BASE       0x400   /* 1024 */
+#define BLE_HS_SM_US_ERR(x)         ((x) ? BLE_HS_ERR_SM_US_BASE + (x) : 0)
+
+#define BLE_HS_ERR_SM_THEM_BASE     0x400   /* 1024 */
+#define BLE_HS_SM_THEM_ERR(x)       ((x) ? BLE_HS_ERR_SM_THEM_BASE + (x) : 0)
 
 struct ble_hs_cfg {
     /** HCI settings. */
@@ -87,6 +90,14 @@ struct ble_hs_cfg {
     uint8_t max_l2cap_chans;
     uint8_t max_l2cap_sig_procs;
     uint8_t max_l2cap_sm_procs;
+
+    /** Security manager settings. */
+    uint8_t sm_io_cap;
+    unsigned sm_oob_data_flag:1;
+    unsigned sm_bonding:1;
+    unsigned sm_mitm:1;
+    unsigned sm_sc:1;
+    unsigned sm_keypress:1;
 };
 
 extern const struct ble_hs_cfg ble_hs_cfg_dflt;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/include/host/ble_l2cap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_l2cap.h b/net/nimble/host/include/host/ble_l2cap.h
index 444f5c1..76c838b 100644
--- a/net/nimble/host/include/host/ble_l2cap.h
+++ b/net/nimble/host/include/host/ble_l2cap.h
@@ -47,9 +47,9 @@ struct ble_hs_conn;
 #define BLE_L2CAP_SIG_OP_FLOW_CTRL_CREDIT   0x16
 #define BLE_L2CAP_SIG_OP_MAX                0x17
 
-#define BLE_L2CAP_ERR_CMD_NOT_UNDERSTOOD    0x0000
-#define BLE_L2CAP_ERR_MTU_EXCEEDED          0x0001
-#define BLE_L2CAP_ERR_INVALID_CID           0x0002
+#define BLE_L2CAP_SIG_ERR_CMD_NOT_UNDERSTOOD    0x0000
+#define BLE_L2CAP_SIG_ERR_MTU_EXCEEDED          0x0001
+#define BLE_L2CAP_SIG_ERR_INVALID_CID           0x0002
 
 #define BLE_L2CAP_SM_OP_PAIR_REQ                0x01
 #define BLE_L2CAP_SM_OP_PAIR_RSP                0x02
@@ -66,6 +66,25 @@ struct ble_hs_conn;
 #define BLE_L2CAP_SM_OP_PAIR_DHKEY_CHECK        0x0d
 #define BLE_L2CAP_SM_OP_PAIR_KEYPRESS_NOTIFY    0x0e
 
+#define BLE_L2CAP_SM_ERR_PASSKEY            0x01
+#define BLE_L2CAP_SM_ERR_OOB                0x02
+#define BLE_L2CAP_SM_ERR_AUTHREQ            0x03
+#define BLE_L2CAP_SM_ERR_CONFIRM_MISMATCH   0x04
+#define BLE_L2CAP_SM_ERR_PAIR_NOT_SUPP      0x05
+#define BLE_L2CAP_SM_ERR_ENC_KEY_SZ         0x06
+#define BLE_L2CAP_SM_ERR_CMD_NOT_SUPP       0x07
+#define BLE_L2CAP_SM_ERR_UNSPECIFIED        0x08
+#define BLE_L2CAP_SM_ERR_REPEATED           0x09
+#define BLE_L2CAP_SM_ERR_INVAL              0x0a
+#define BLE_L2CAP_SM_ERR_DHKEY              0x0b
+#define BLE_L2CAP_SM_ERR_NUM_CMP            0x0c
+#define BLE_L2CAP_SM_ERR_ALREADY            0x0d
+#define BLE_L2CAP_SM_ERR_CROSS_TRANS        0x0e
+
+#define BLE_L2CAP_SM_PAIR_ALG_JW            0
+#define BLE_L2CAP_SM_PAIR_ALG_PASSKEY       1
+#define BLE_L2CAP_SM_PAIR_ALG_OOB           2
+
 typedef void ble_l2cap_sig_update_fn(int status, void *arg);
 
 struct ble_l2cap_sig_update_params {
@@ -79,4 +98,7 @@ int ble_l2cap_sig_update(uint16_t conn_handle,
                          struct ble_l2cap_sig_update_params *params,
                          ble_l2cap_sig_update_fn *cb, void *cb_arg);
 
+
+int ble_l2cap_sm_set_tk(uint16_t conn_handle, uint8_t *tk);
+
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/pkg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/host/pkg.yml b/net/nimble/host/pkg.yml
index 679c054..ef4cf2c 100644
--- a/net/nimble/host/pkg.yml
+++ b/net/nimble/host/pkg.yml
@@ -38,5 +38,7 @@ pkg.req_apis:
 
 # Satisfy capability dependencies for the self-contained test executable.
 pkg.deps.SELFTEST: libs/console/stub
-pkg.cflags.SELFTEST: -DPHONY_TRANSPORT
+pkg.cflags.SELFTEST:
+    - -DPHONY_TRANSPORT=1
+    - -DNIMBLE_OPT_SM=1
 pkg.cflags.TEST: -DBLE_HS_DEBUG

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/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 324f8da..eab7d50 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -3068,20 +3068,13 @@ done:
  *****************************************************************************/
 
 void
-ble_gap_encryption_changed(uint16_t conn_handle,
-                           struct ble_gap_sec_params *sec_params)
+ble_gap_security_event(uint16_t conn_handle, int status,
+                       struct ble_gap_sec_params *sec_params)
 {
     struct ble_gap_conn_ctxt ctxt;
     struct ble_gap_snapshot snap;
     struct ble_hs_conn *conn;
 
-    if (!sec_params->enc_enabled) {
-        /* XXX: Encryption got disabled.  Does this ever happen?  If so, the
-         * application needs to be notified of the change.
-         */
-        return;
-    }
-
     ble_hs_conn_lock();
 
     conn = ble_hs_conn_find(conn_handle);
@@ -3100,25 +3093,6 @@ ble_gap_encryption_changed(uint16_t conn_handle,
     memset(&ctxt, 0, sizeof ctxt);
     ctxt.desc = &snap.desc;
     ctxt.sec_params = sec_params;
-    ble_gap_call_conn_cb(BLE_GAP_EVENT_SECURITY, 0, &ctxt,
-                         snap.cb, snap.cb_arg);
-}
-
-void
-ble_gap_security_fail(uint16_t conn_handle, int status)
-{
-    struct ble_gap_conn_ctxt ctxt;
-    struct ble_gap_snapshot snap;
-    int rc;
-
-    rc = ble_gap_find_snapshot(conn_handle, &snap);
-    if (rc != 0) {
-        /* No longer connected. */
-        return;
-    }
-
-    memset(&ctxt, 0, sizeof ctxt);
-    ctxt.desc = &snap.desc;
     ble_gap_call_conn_cb(BLE_GAP_EVENT_SECURITY, status, &ctxt,
                          snap.cb, snap.cb_arg);
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/src/ble_gap_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap_priv.h b/net/nimble/host/src/ble_gap_priv.h
index 7facca9..d290480 100644
--- a/net/nimble/host/src/ble_gap_priv.h
+++ b/net/nimble/host/src/ble_gap_priv.h
@@ -74,9 +74,8 @@ void ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt);
 void ble_gap_rx_param_req(struct hci_le_conn_param_req *evt);
 int ble_gap_rx_l2cap_update_req(uint16_t conn_handle,
                                 struct ble_gap_upd_params *params);
-void ble_gap_encryption_changed(uint16_t conn_handle,
-                                struct ble_gap_sec_params *sec_params);
-void ble_gap_security_fail(uint16_t conn_handle, int status);
+void ble_gap_security_event(uint16_t conn_handle, int status, 
+                            struct ble_gap_sec_params *sec_params);
 int ble_gap_master_in_progress(void);
 int ble_gap_slave_in_progress(void);
 int ble_gap_update_in_progress(uint16_t conn_handle);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/src/ble_hs_cfg.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_cfg.c b/net/nimble/host/src/ble_hs_cfg.c
index 9e79bbe..860ef3c 100644
--- a/net/nimble/host/src/ble_hs_cfg.c
+++ b/net/nimble/host/src/ble_hs_cfg.c
@@ -50,6 +50,14 @@ const struct ble_hs_cfg ble_hs_cfg_dflt = {
     .max_l2cap_chans = 16,
     .max_l2cap_sig_procs = 8,
     .max_l2cap_sm_procs = 1,
+
+    /** Security manager settings. */
+    .sm_io_cap = 3,
+    .sm_oob_data_flag = 0,
+    .sm_bonding = 0,
+    .sm_mitm = 0,
+    .sm_sc = 0,
+    .sm_keypress = 0,
 };
 
 struct ble_hs_cfg ble_hs_cfg;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/src/ble_l2cap_sig.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig.c b/net/nimble/host/src/ble_l2cap_sig.c
index 112d541..f0e3098 100644
--- a/net/nimble/host/src/ble_l2cap_sig.c
+++ b/net/nimble/host/src/ble_l2cap_sig.c
@@ -430,7 +430,7 @@ ble_l2cap_sig_update_req_rx(uint16_t conn_handle,
     /* Only a master can process an update request. */
     if (!is_master) {
         ble_l2cap_sig_reject_tx(conn_handle, hdr->identifier,
-                                BLE_L2CAP_ERR_CMD_NOT_UNDERSTOOD);
+                                BLE_L2CAP_SIG_ERR_CMD_NOT_UNDERSTOOD);
         return BLE_HS_ENOTSUP;
     }
 
@@ -620,7 +620,7 @@ ble_l2cap_sig_rx(uint16_t conn_handle, struct os_mbuf **om)
     rx_cb = ble_l2cap_sig_dispatch_get(hdr.op);
     if (rx_cb == NULL) {
         ble_l2cap_sig_reject_tx(conn_handle, hdr.identifier,
-                                BLE_L2CAP_ERR_CMD_NOT_UNDERSTOOD);
+                                BLE_L2CAP_SIG_ERR_CMD_NOT_UNDERSTOOD);
         rc = BLE_HS_ENOTSUP;
     } else {
         rc = rx_cb(conn_handle, &hdr, om);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/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 be2f6f1..6e13952 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -40,14 +40,12 @@
 
 #define BLE_L2CAP_SM_PROC_F_INITIATOR           0x01
 
-#define BLE_L2CAP_SM_KEYGEN_METHOD_JW           0
-
 typedef uint16_t ble_l2cap_sm_proc_flags;
 
 struct ble_l2cap_sm_proc {
     struct ble_fsm_proc fsm_proc;
     ble_l2cap_sm_proc_flags flags;
-    uint8_t keygen_method;
+    uint8_t pair_alg;
 
     /* XXX: Minimum security requirements. */
 
@@ -55,6 +53,7 @@ struct ble_l2cap_sm_proc {
         struct {
             struct ble_l2cap_sm_pair_cmd pair_req;
             struct ble_l2cap_sm_pair_cmd pair_rsp;
+            uint8_t tk[16];
             uint8_t confirm_their[16];
             uint8_t rand_our[16];
             uint8_t rand_their[16];
@@ -349,13 +348,44 @@ ble_l2cap_sm_rx_noop(uint16_t conn_handle, uint8_t op, struct os_mbuf
**om)
     return 0;
 }
 
+static int
+ble_l2cap_sm_request_tk(struct ble_l2cap_sm_proc *proc)
+{
+    if (proc->pair_alg == BLE_L2CAP_SM_PAIR_ALG_JW) {
+        ble_l2cap_sm_proc_set_pending(proc);
+    } else {
+        /* XXX: Ask application for TK. */
+    }
+    return 0;
+}
+
+static void
+ble_l2cap_sm_sec_params(struct ble_l2cap_sm_proc *proc,
+                        struct ble_gap_sec_params *out_sec_params,
+                        int enc_enabled)
+{
+    out_sec_params->pair_alg = proc->pair_alg;
+    out_sec_params->enc_enabled = enc_enabled;
+    out_sec_params->auth_enabled = 0; // XXX
+}
+
+static void
+ble_l2cap_sm_gap_event(struct ble_l2cap_sm_proc *proc, int status,
+                       int enc_enabled)
+{
+    struct ble_gap_sec_params sec_params;
+
+    ble_l2cap_sm_sec_params(proc, &sec_params, enc_enabled);
+    ble_gap_security_event(proc->fsm_proc.conn_handle, status, &sec_params);
+}
+
 /*****************************************************************************
  * $pair                                                                     *
  *****************************************************************************/
 
 static int
 ble_l2cap_sm_pair_req_handle(struct ble_l2cap_sm_proc *proc,
-                            struct ble_l2cap_sm_pair_cmd *req)
+                             struct ble_l2cap_sm_pair_cmd *req)
 {
     proc->phase_1_2.pair_req = *req;
     ble_l2cap_sm_proc_set_pending(proc);
@@ -367,27 +397,37 @@ static int
 ble_l2cap_sm_pair_rsp_handle(struct ble_l2cap_sm_proc *proc,
                              struct ble_l2cap_sm_pair_cmd *rsp)
 {
+    int rc;
+
     proc->phase_1_2.pair_rsp = *rsp;
+
     proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_CONFIRM;
-    ble_l2cap_sm_proc_set_pending(proc);
+    proc->fsm_proc.flags &= ~BLE_FSM_PROC_F_EXPECTING;
 
     /* XXX: Assume legacy "Just Works" for now. */
-    proc->keygen_method = BLE_L2CAP_SM_KEYGEN_METHOD_JW;
+    proc->pair_alg = BLE_L2CAP_SM_PAIR_ALG_JW;
+
+    rc = ble_l2cap_sm_request_tk(proc);
+    if (rc != 0) {
+        ble_l2cap_sm_set_fail_state(proc, rc);
+        return rc;
+    }
 
     return 0;
 }
 
-
 static int
 ble_l2cap_sm_pair_kick(struct ble_l2cap_sm_proc *proc)
 {
     struct ble_l2cap_sm_pair_cmd cmd;
     int rc;
 
-    /* XXX: Assume legacy "Just Works" for now. */
-    cmd.io_cap = 3;
-    cmd.oob_data_flag = 0;
-    cmd.authreq = 0;
+    cmd.io_cap = ble_hs_cfg.sm_io_cap;
+    cmd.oob_data_flag = ble_hs_cfg.sm_oob_data_flag;
+    cmd.authreq = (ble_hs_cfg.sm_bonding << 0)  |
+                  (ble_hs_cfg.sm_mitm << 2)     |
+                  (ble_hs_cfg.sm_sc << 3)       |
+                  (ble_hs_cfg.sm_keypress << 4);
     cmd.max_enc_key_size = 16;
     cmd.init_key_dist = 0;
     cmd.resp_key_dist = 0;
@@ -401,7 +441,7 @@ ble_l2cap_sm_pair_kick(struct ble_l2cap_sm_proc *proc)
     if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
         proc->phase_1_2.pair_req = cmd;
     } else {
-        proc->keygen_method = BLE_L2CAP_SM_KEYGEN_METHOD_JW;
+        proc->pair_alg = BLE_L2CAP_SM_PAIR_ALG_JW;
         proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_CONFIRM;
         proc->phase_1_2.pair_rsp = cmd;
     }
@@ -419,8 +459,6 @@ ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc,
                                   uint8_t *iat, uint8_t *rat,
                                   uint8_t *ia, uint8_t *ra)
 {
-    static uint8_t zeros[16];
-
     struct ble_hs_conn *conn;
     int rc;
 
@@ -447,7 +485,7 @@ ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc,
         return BLE_HS_ENOTCONN;
     }
 
-    memcpy(k, zeros, 16); /* XXX: Assume legacy "Just Works." */
+    memcpy(k, proc->phase_1_2.tk, sizeof proc->phase_1_2.tk);
 
     rc = ble_l2cap_sm_pair_cmd_write(
         preq, BLE_L2CAP_SM_HDR_SZ + BLE_L2CAP_SM_PAIR_CMD_SZ, 1,
@@ -514,12 +552,20 @@ static int
 ble_l2cap_sm_confirm_handle(struct ble_l2cap_sm_proc *proc,
                             struct ble_l2cap_sm_pair_confirm *cmd)
 {
+    int rc;
+
     memcpy(proc->phase_1_2.confirm_their, cmd->value, 16);
 
     if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
         proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_RANDOM;
+        ble_l2cap_sm_proc_set_pending(proc);
+    } else {
+        rc = ble_l2cap_sm_request_tk(proc);
+        if (rc != 0) {
+            ble_l2cap_sm_set_fail_state(proc, rc);
+            return rc;
+        }
     }
-    ble_l2cap_sm_proc_set_pending(proc);
 
     return 0;
 }
@@ -605,6 +651,9 @@ ble_l2cap_sm_fail_kick(struct ble_l2cap_sm_proc *proc)
     cmd.reason = proc->fail.reason;
     ble_l2cap_sm_pair_fail_tx(proc->fsm_proc.conn_handle, &cmd);
 
+    /* Notify application of failure. */
+    ble_l2cap_sm_gap_event(proc, BLE_HS_SM_US_ERR(cmd.reason), 0);
+
     return BLE_HS_EDONE;
 }
 
@@ -612,8 +661,7 @@ static int
 ble_l2cap_sm_fail_handle(struct ble_l2cap_sm_proc *proc,
                          struct ble_l2cap_sm_pair_fail *cmd)
 {
-    ble_gap_security_fail(proc->fsm_proc.conn_handle,
-                          BLE_HS_SM_ERR(cmd->reason));
+    ble_l2cap_sm_gap_event(proc, BLE_HS_SM_THEM_ERR(cmd->reason), 0);
 
     /* Procedure should now be terminated (return nonzero). */
     return 1;
@@ -628,7 +676,7 @@ ble_l2cap_sm_lt_key_req_reply_ack_handle(struct ble_l2cap_sm_proc *proc,
                                          struct ble_hci_ack *ack)
 {
     if (ack->bha_status != 0) {
-        ble_gap_security_fail(proc->fsm_proc.conn_handle, ack->bha_status);
+        ble_l2cap_sm_gap_event(proc, ack->bha_status, 0);
     } else {
         proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_ENC_CHANGE;
     }
@@ -664,7 +712,7 @@ ble_l2cap_sm_lt_key_req_kick(struct ble_l2cap_sm_proc *proc)
     rc = ble_hci_sched_enqueue(ble_l2cap_sm_lt_key_req_reply_tx, proc,
                                &proc->hci.handle);
     if (rc != 0) {
-        ble_gap_security_fail(proc->fsm_proc.conn_handle, rc);
+        ble_l2cap_sm_gap_event(proc, rc, 0);
         return BLE_HS_EDONE;
     }
 
@@ -678,15 +726,13 @@ ble_l2cap_sm_lt_key_req_handle(struct ble_l2cap_sm_proc *proc,
                                struct hci_le_lt_key_req *evt)
 {
     uint8_t key[16];
-    /* XXX: Assume legacy "Just Works". */
-    uint8_t k[16] = {0};
     int rc;
 
     /* Generate the key. */
-    rc = ble_l2cap_sm_alg_s1(k, proc->phase_1_2.rand_our,
+    rc = ble_l2cap_sm_alg_s1(proc->phase_1_2.tk, proc->phase_1_2.rand_our,
                              proc->phase_1_2.rand_their, key);
     if (rc != 0) {
-        ble_gap_security_fail(proc->fsm_proc.conn_handle, rc);
+        ble_l2cap_sm_gap_event(proc, rc, 0);
         return rc;
     }
 
@@ -945,7 +991,6 @@ ble_l2cap_sm_rx_lt_key_req_reply_ack(struct ble_hci_ack *ack, void *arg)
 void
 ble_l2cap_sm_rx_encryption_change(struct hci_encrypt_change *evt)
 {
-    struct ble_gap_sec_params sec_params;
     struct ble_l2cap_sm_proc *proc;
 
     proc = ble_l2cap_sm_proc_extract(
@@ -960,13 +1005,10 @@ ble_l2cap_sm_rx_encryption_change(struct hci_encrypt_change *evt)
     }
 
     if (evt->status != 0) {
-        ble_gap_security_fail(evt->connection_handle,
-                              BLE_HS_SM_ERR(evt->status));
+        ble_l2cap_sm_gap_event(proc, BLE_HS_HCI_ERR(evt->status), 0);
     } else {
-        sec_params.enc_type = proc->keygen_method; // XXX
-        sec_params.enc_enabled = evt->encryption_enabled & 0x01; /* LE bit. */
-        sec_params.auth_enabled = 0; // XXX
-        ble_gap_encryption_changed(evt->connection_handle, &sec_params);
+        ble_l2cap_sm_gap_event(proc, 0,
+                               evt->encryption_enabled & 0x01 /* LE bit. */);
     }
 
     /* The pairing procedure is now complete. */
@@ -1034,6 +1076,29 @@ ble_l2cap_sm_create_chan(void)
     return chan;
 }
 
+int
+ble_l2cap_sm_set_tk(uint16_t conn_handle, uint8_t *tk)
+{
+    struct ble_l2cap_sm_proc *proc;
+
+    proc = ble_l2cap_sm_proc_extract(
+        &(struct ble_l2cap_sm_extract_arg) {
+            .conn_handle = conn_handle,
+            .op = BLE_L2CAP_SM_PROC_OP_CONFIRM,
+            .initiator = -1,
+        }
+    );
+    if (proc == NULL) {
+        return BLE_HS_ENOENT;
+    }
+
+    memcpy(proc->phase_1_2.tk, tk, 16);
+
+    ble_l2cap_sm_proc_set_pending(proc);
+
+    return 0;
+}
+
 /**
  * Lock restrictions:
  *     o Caller unlocks ble_hs_conn.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/src/ble_l2cap_sm.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm.h b/net/nimble/host/src/ble_l2cap_sm.h
index 5051bd6..e7d69cc 100644
--- a/net/nimble/host/src/ble_l2cap_sm.h
+++ b/net/nimble/host/src/ble_l2cap_sm.h
@@ -23,21 +23,6 @@
 struct ble_gap_sec_params;
 struct hci_le_lt_key_req;
 
-#define BLE_L2CAP_SM_ERR_PASSKEY            0x01
-#define BLE_L2CAP_SM_ERR_OOB                0x02
-#define BLE_L2CAP_SM_ERR_AUTHREQ            0x03
-#define BLE_L2CAP_SM_ERR_CONFIRM_MISMATCH   0x04
-#define BLE_L2CAP_SM_ERR_PAIR_NOT_SUPP      0x05
-#define BLE_L2CAP_SM_ERR_ENC_KEY_SZ         0x06
-#define BLE_L2CAP_SM_ERR_CMD_NOT_SUPP       0x07
-#define BLE_L2CAP_SM_ERR_UNSPECIFIED        0x08
-#define BLE_L2CAP_SM_ERR_REPEATED           0x09
-#define BLE_L2CAP_SM_ERR_INVAL              0x0a
-#define BLE_L2CAP_SM_ERR_DHKEY              0x0b
-#define BLE_L2CAP_SM_ERR_NUM_CMP            0x0c
-#define BLE_L2CAP_SM_ERR_ALREADY            0x0d
-#define BLE_L2CAP_SM_ERR_CROSS_TRANS        0x0e
-
 #define BLE_L2CAP_SM_MTU            65
 
 #define BLE_L2CAP_SM_HDR_SZ         1

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/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 2ed093a..33fe1b1 100644
--- a/net/nimble/host/src/test/ble_l2cap_sm_test.c
+++ b/net/nimble/host/src/test/ble_l2cap_sm_test.c
@@ -29,6 +29,10 @@
 
 #if NIMBLE_OPT_SM
 
+int ble_l2cap_sm_test_gap_event;
+int ble_l2cap_sm_test_gap_status;
+struct ble_gap_sec_params ble_l2cap_sm_test_sec_params;
+
 /*****************************************************************************
  * $util                                                                     *
  *****************************************************************************/
@@ -44,20 +48,23 @@ static void
 ble_l2cap_sm_test_util_init(void)
 {
     ble_hs_test_util_init();
-    //ble_l2cap_test_update_status = -1;
-    //ble_l2cap_test_update_arg = (void *)(uintptr_t)-1;
+
+    ble_l2cap_sm_test_gap_event = -1;
+    ble_l2cap_sm_test_gap_status = -1;
+    memset(&ble_l2cap_sm_test_sec_params, 0xff,
+           sizeof ble_l2cap_sm_test_sec_params);
 }
 
 static int
 ble_l2cap_sm_test_util_conn_cb(int event, int status,
                                struct ble_gap_conn_ctxt *ctxt, void *arg)
 {
-    int *accept;
-
     switch (event) {
-    case BLE_GAP_EVENT_L2CAP_UPDATE_REQ:
-        accept = arg;
-        return !*accept;
+    case BLE_GAP_EVENT_SECURITY:
+        ble_l2cap_sm_test_gap_event = event;
+        ble_l2cap_sm_test_gap_status = status;
+        ble_l2cap_sm_test_sec_params = *ctxt->sec_params;
+        return 0;
 
     default:
         return 0;
@@ -321,6 +328,8 @@ ble_l2cap_sm_test_util_peer_lgcy_good(
     struct ble_l2cap_sm_pair_confirm *confirm_rsp,
     struct ble_l2cap_sm_pair_random *random_req,
     struct ble_l2cap_sm_pair_random *random_rsp,
+    int pair_alg,
+    uint8_t *tk,
     uint8_t *stk,
     uint64_t r,
     uint16_t ediv)
@@ -392,8 +401,22 @@ ble_l2cap_sm_test_util_peer_lgcy_good(
     ble_l2cap_sm_test_util_rx_enc_change(2, 0, 1);
 
     /* Pairing should now be complete. */
-    TEST_ASSERT(conn->bhc_sec_params.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
+
+    /* Verify that security callback was executed. */
+    TEST_ASSERT(ble_l2cap_sm_test_gap_event == BLE_GAP_EVENT_SECURITY);
+    TEST_ASSERT(ble_l2cap_sm_test_gap_status == 0);
+    TEST_ASSERT(ble_l2cap_sm_test_sec_params.pair_alg == pair_alg);
+    TEST_ASSERT(ble_l2cap_sm_test_sec_params.enc_enabled);
+    TEST_ASSERT(!ble_l2cap_sm_test_sec_params.auth_enabled);
+
+    /* Verify that connection has correct security state. */
+    TEST_ASSERT(ble_l2cap_sm_test_sec_params.pair_alg ==
+                conn->bhc_sec_params.pair_alg);
+    TEST_ASSERT(ble_l2cap_sm_test_sec_params.enc_enabled ==
+                conn->bhc_sec_params.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_test_sec_params.auth_enabled ==
+                conn->bhc_sec_params.auth_enabled);
 }
 
 static void
@@ -449,9 +472,26 @@ ble_l2cap_sm_test_util_peer_lgcy_fail(
 
     /* The proc should now be freed. */
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
+
+    /* Verify that security callback was executed. */
+    TEST_ASSERT(ble_l2cap_sm_test_gap_event == BLE_GAP_EVENT_SECURITY);
+    TEST_ASSERT(ble_l2cap_sm_test_gap_status ==
+                BLE_HS_SM_US_ERR(BLE_L2CAP_SM_ERR_CONFIRM_MISMATCH));
+    TEST_ASSERT(ble_l2cap_sm_test_sec_params.pair_alg ==
+                BLE_L2CAP_SM_PAIR_ALG_JW);
+    TEST_ASSERT(!ble_l2cap_sm_test_sec_params.enc_enabled);
+    TEST_ASSERT(!ble_l2cap_sm_test_sec_params.auth_enabled);
+
+    /* Verify that connection has correct security state. */
+    TEST_ASSERT(ble_l2cap_sm_test_sec_params.pair_alg ==
+                conn->bhc_sec_params.pair_alg);
+    TEST_ASSERT(ble_l2cap_sm_test_sec_params.enc_enabled ==
+                conn->bhc_sec_params.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_test_sec_params.auth_enabled ==
+                conn->bhc_sec_params.auth_enabled);
 }
 
-TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_good)
+TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_jw_good)
 {
     ble_l2cap_sm_test_util_peer_lgcy_good(
         ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
@@ -496,6 +536,8 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_good)
                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             },
         } }),
+        BLE_L2CAP_SM_PAIR_ALG_JW,
+        NULL,
         ((uint8_t[16]) {
             0xe6, 0xb3, 0x05, 0xd4, 0xc3, 0x67, 0xf0, 0x45,
             0x38, 0x8f, 0xe7, 0x33, 0x0d, 0x51, 0x8e, 0xa4,
@@ -558,7 +600,7 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_fail)
 
 TEST_SUITE(ble_l2cap_sm_test_suite)
 {
-    ble_l2cap_sm_test_case_peer_lgcy_good();
+    ble_l2cap_sm_test_case_peer_lgcy_jw_good();
     ble_l2cap_sm_test_case_peer_lgcy_fail();
 }
 #endif


Mime
View raw message