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/09 04:54:06 UTC

[4/4] incubator-mynewt-core git commit: BLE host - remove ble_l2cap_sm_process_status().

BLE host - remove ble_l2cap_sm_process_status().

This function was ill-conceived.


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

Branch: refs/heads/develop
Commit: e76defb0437e1811dffe3f630405627eb6b3bf2a
Parents: 2a6cf99
Author: Christopher Collins <cc...@apache.org>
Authored: Sun May 8 21:33:32 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Sun May 8 21:53:50 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/src/ble_l2cap_sm.c           | 120 ++---
 net/nimble/host/src/test/ble_l2cap_sm_test.c | 578 +++++++++++++++-------
 2 files changed, 463 insertions(+), 235 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e76defb0/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 60cbae8..376b2f8 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -403,30 +403,6 @@ ble_l2cap_sm_gap_event(struct ble_l2cap_sm_proc *proc, int status,
     ble_gap_security_event(proc->conn_handle, status, &sec_state);
 }
 
-/* We must call this function when the host is unlocked because in
- * failure conditions it will transmit which requires that we lock it
-  */
-static int
-ble_l2cap_sm_process_status(struct ble_l2cap_sm_proc *proc, int status,
-                            uint8_t sm_status, int call_cb, int tx_fail)
-{
-    if (proc == NULL) {
-        status = BLE_HS_ENOENT;
-    } else if (status != 0) {
-        if (tx_fail) {
-            ble_hs_lock();
-            ble_l2cap_sm_pair_fail_tx(proc->conn_handle, sm_status);
-            ble_hs_unlock();
-        }
-        if (call_cb) {
-            ble_l2cap_sm_gap_event(proc, status, 0);
-        }
-        ble_l2cap_sm_proc_free(proc);
-    }
-
-    return status;
-}
-
 static int
 ble_l2cap_sm_proc_matches(struct ble_l2cap_sm_proc *proc, uint16_t conn_handle,
                           uint8_t state, int is_initiator)
@@ -1037,7 +1013,7 @@ ble_l2cap_sm_pair_req_handle(struct ble_l2cap_sm_proc *proc,
     }
     if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) {
         *out_sm_status = BLE_L2CAP_SM_ERR_CMD_NOT_SUPP;
-        return BLE_HS_EROLE;
+        return BLE_HS_SM_US_ERR(BLE_L2CAP_SM_ERR_CMD_NOT_SUPP);
     }
 
     if (!ble_l2cap_sm_pair_cmd_is_valid(req)) {
@@ -1310,20 +1286,22 @@ ble_l2cap_sm_rx_key_exchange(uint16_t conn_handle, uint8_t op,
             ble_l2cap_sm_signing_info_handle(proc, &u.signing_info);
             break;
         }
-    }
 
-    /* did we finish RX keys */
-    rc = 0;
-    if (!proc->rx_key_flags) {
-        if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
-            /* time for us to send our keys */
-            rc = ble_l2cap_sm_key_exchange_go(proc, &sm_status);
+        /* did we finish RX keys */
+        rc = 0;
+        if (!proc->rx_key_flags) {
+            if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
+                /* time for us to send our keys */
+                rc = ble_l2cap_sm_key_exchange_go(proc, &sm_status);
+            }
+            sm_end = 1;
         }
-        sm_end = 1;
-    }
 
-    if (rc != 0 || sm_end) {
-        ble_l2cap_sm_proc_remove(proc, prev);
+        if (rc != 0 || sm_end) {
+            ble_l2cap_sm_proc_remove(proc, prev);
+        }
+    } else {
+        rc = BLE_HS_ENOENT;
     }
 
     ble_hs_unlock();
@@ -1331,14 +1309,15 @@ ble_l2cap_sm_rx_key_exchange(uint16_t conn_handle, uint8_t op,
     /* a successful ending of the link */
     if (rc == 0) {
         if (sm_end) {
-            /* TODO put error code here */
             ble_l2cap_sm_gap_event(proc, 0, 1);
             ble_l2cap_sm_key_exchange_events(proc);
             ble_l2cap_sm_proc_free(proc);
         }
     } else {
-        rc = ble_l2cap_sm_process_status(proc, rc, sm_status, 1, 1);
+        ble_l2cap_sm_gap_event(proc, sm_status, 0);
+        ble_l2cap_sm_proc_free(proc);
     }
+
     return rc;
 }
 
@@ -1400,14 +1379,20 @@ ble_l2cap_sm_rx_pair_req(uint16_t conn_handle, uint8_t op,
         }
     }
 
+    if (rc != 0) {
+        ble_l2cap_sm_pair_fail_tx(proc->conn_handle, sm_status);
+    }
+
     ble_hs_unlock();
 
-    /* This has to be done after the unlock */
-    if (passkey_action != BLE_GAP_PKACT_NONE) {
-        ble_gap_passkey_event(proc->conn_handle,sm_status, passkey_action);
+    if (rc == 0) {
+        if (passkey_action != BLE_GAP_PKACT_NONE) {
+            ble_gap_passkey_event(conn_handle, sm_status, passkey_action);
+        }
+    } else {
+        ble_l2cap_sm_proc_free(proc);
     }
 
-    rc = ble_l2cap_sm_process_status(proc, rc, sm_status, 0, 1);
     return rc;
 }
 
@@ -1443,16 +1428,19 @@ ble_l2cap_sm_rx_pair_rsp(uint16_t conn_handle, uint8_t op,
                                           &passkey_action);
         if (rc != 0) {
             ble_l2cap_sm_proc_remove(proc, prev);
+            ble_l2cap_sm_pair_fail_tx(conn_handle, sm_status);
         }
     }
+
     ble_hs_unlock();
 
-    /* The GAP callback can only be executed after the unlock. */
-    if (passkey_action != BLE_GAP_PKACT_NONE) {
-        ble_gap_passkey_event(proc->conn_handle,sm_status, passkey_action);
+    if (rc != 0) {
+        ble_l2cap_sm_gap_event(proc, rc, 0);
+        ble_l2cap_sm_proc_free(proc);
+    } else if (passkey_action != BLE_GAP_PKACT_NONE) {
+        ble_gap_passkey_event(conn_handle, sm_status, passkey_action);
     }
 
-    rc = ble_l2cap_sm_process_status(proc, rc, sm_status, 1, 1);
     return rc;
 }
 
@@ -1482,11 +1470,16 @@ ble_l2cap_sm_rx_pair_confirm(uint16_t conn_handle, uint8_t op,
         rc = ble_l2cap_sm_confirm_handle(proc, &cmd, &sm_status);
         if (rc != 0) {
             ble_l2cap_sm_proc_remove(proc, prev);
+            ble_l2cap_sm_pair_fail_tx(conn_handle, sm_status);
         }
     }
     ble_hs_unlock();
 
-    rc = ble_l2cap_sm_process_status(proc, rc, sm_status, 1, 1);
+    if (rc != 0) {
+        ble_l2cap_sm_gap_event(proc, rc, 0);
+        ble_l2cap_sm_proc_free(proc);
+    }
+
     return rc;
 }
 
@@ -1518,11 +1511,16 @@ ble_l2cap_sm_rx_pair_random(uint16_t conn_handle, uint8_t op,
         rc = ble_l2cap_sm_random_handle(proc, &cmd, &sm_status);
         if (rc != 0) {
             ble_l2cap_sm_proc_remove(proc, prev);
+            ble_l2cap_sm_pair_fail_tx(conn_handle, sm_status);
         }
     }
     ble_hs_unlock();
 
-    rc = ble_l2cap_sm_process_status(proc, rc, sm_status, 1, 1);
+    if (rc != 0) {
+        ble_l2cap_sm_gap_event(proc, rc, 0);
+        ble_l2cap_sm_proc_free(proc);
+    }
+
     return rc;
 }
 
@@ -1552,9 +1550,14 @@ ble_l2cap_sm_rx_pair_fail(uint16_t conn_handle, uint8_t op,
     }
     ble_hs_unlock();
 
-    rc = ble_l2cap_sm_process_status(proc, BLE_HS_SM_THEM_ERR(cmd.reason),
-                                     0, 1, 0);
-    return rc;
+    if (proc == NULL) {
+        return BLE_HS_ENOENT;
+    }
+
+    ble_l2cap_sm_gap_event(proc, BLE_HS_SM_THEM_ERR(cmd.reason), 0);
+    ble_l2cap_sm_proc_free(proc);
+
+    return 0;
 }
 
 static int
@@ -1666,7 +1669,10 @@ ble_l2cap_sm_rx_lt_key_req(struct hci_le_lt_key_req *evt)
             rc = ble_l2cap_sm_lt_key_req_ltk_handle(evt);
         }
     } else if (proc != NULL) {
-        rc = ble_l2cap_sm_process_status(proc, rc, 0, 1, 0);
+        ble_l2cap_sm_gap_event(proc, rc, 0);
+        ble_l2cap_sm_proc_free(proc);
+    } else {
+        rc = BLE_HS_ENOENT;
     }
 
     return rc;
@@ -1707,12 +1713,10 @@ ble_l2cap_sm_rx_encryption_change(struct hci_encrypt_change *evt)
 
     ble_hs_unlock();
 
-    if (proc != NULL && do_key_exchange == 0 && rc == 0) {
+    if (rc != 0 || (proc != NULL && do_key_exchange == 0)) {
         /* The pairing procedure is now complete. */
         ble_l2cap_sm_gap_event(proc, BLE_HS_HCI_ERR(evt->status), enc_enabled);
         ble_l2cap_sm_proc_free(proc);
-    } else if (rc) {
-        ble_l2cap_sm_process_status(proc, rc, sm_status, 1, 1);
     }
 }
 
@@ -1960,12 +1964,14 @@ ble_l2cap_sm_set_tk(uint16_t conn_handle, struct passkey_action *pkey)
 set_tk_return:
     if (proc != NULL && rc != 0) {
         ble_l2cap_sm_proc_remove(proc, prev);
+        ble_l2cap_sm_pair_fail_tx(conn_handle, sm_error);
     }
 
     ble_hs_unlock();
 
-    if (rc != 0) {
-        rc = ble_l2cap_sm_process_status(proc, rc, sm_error, 1, 1);
+    if (proc != NULL && rc != 0) {
+        ble_l2cap_sm_gap_event(proc, rc, 0);
+        ble_l2cap_sm_proc_free(proc);
     }
 
     return rc;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e76defb0/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 dd22a73..22077c1 100644
--- a/net/nimble/host/src/test/ble_l2cap_sm_test.c
+++ b/net/nimble/host/src/test/ble_l2cap_sm_test.c
@@ -66,14 +66,13 @@ ble_l2cap_sm_test_util_conn_cb(int event, int status,
                                struct ble_gap_conn_ctxt *ctxt, void *arg)
 {
     struct ble_l2cap_sm_test_ltk_info *ltk_info;
-
-    ble_l2cap_sm_test_gap_event = event;
-    ble_l2cap_sm_test_gap_status = status;
+    int rc;
 
     switch (event) {
     case BLE_GAP_EVENT_SECURITY:
         ble_l2cap_sm_test_sec_state = ctxt->desc->sec_state;
-        return 0;
+        rc = 0;
+        break;
 
     case BLE_GAP_EVENT_LTK_REQUEST:
         ltk_info = arg;
@@ -88,19 +87,26 @@ ble_l2cap_sm_test_util_conn_cb(int event, int status,
 
         ble_l2cap_sm_test_ltk_params = *ctxt->ltk_params;
         if (ltk_info == NULL) {
-            return -1;
+            rc = -1;
         } else {
-            return 0;
+            rc = 0;
         }
+        break;
 
     default:
         return 0;
     }
+
+    ble_l2cap_sm_test_gap_event = event;
+    ble_l2cap_sm_test_gap_status = status;
+
+    return rc;
 }
 
 static void
 ble_l2cap_sm_test_util_rx_pair_cmd(struct ble_hs_conn *conn, uint8_t op,
-                                   struct ble_l2cap_sm_pair_cmd *cmd)
+                                   struct ble_l2cap_sm_pair_cmd *cmd,
+                                   int rx_status)
 {
     struct hci_data_hdr hci_hdr;
     struct os_mbuf *om;
@@ -125,21 +131,25 @@ ble_l2cap_sm_test_util_rx_pair_cmd(struct ble_hs_conn *conn, uint8_t op,
 
     rc = ble_hs_test_util_l2cap_rx_first_frag(conn, BLE_L2CAP_CID_SM, &hci_hdr,
                                               om);
-    TEST_ASSERT_FATAL(rc == 0);
+    TEST_ASSERT(rc == rx_status);
 }
 
 static void
 ble_l2cap_sm_test_util_rx_pair_req(struct ble_hs_conn *conn,
-                                   struct ble_l2cap_sm_pair_cmd *req)
+                                   struct ble_l2cap_sm_pair_cmd *req,
+                                   int rx_status)
 {
-    ble_l2cap_sm_test_util_rx_pair_cmd(conn, BLE_L2CAP_SM_OP_PAIR_REQ, req);
+    ble_l2cap_sm_test_util_rx_pair_cmd(conn, BLE_L2CAP_SM_OP_PAIR_REQ, req,
+                                       rx_status);
 }
 
 static void
 ble_l2cap_sm_test_util_rx_pair_rsp(struct ble_hs_conn *conn,
-                                   struct ble_l2cap_sm_pair_cmd *rsp)
+                                   struct ble_l2cap_sm_pair_cmd *rsp,
+                                   int rx_status)
 {
-    ble_l2cap_sm_test_util_rx_pair_cmd(conn, BLE_L2CAP_SM_OP_PAIR_RSP, rsp);
+    ble_l2cap_sm_test_util_rx_pair_cmd(conn, BLE_L2CAP_SM_OP_PAIR_RSP, rsp,
+                                       rx_status);
 }
 
 static void
@@ -392,105 +402,217 @@ ble_l2cap_sm_test_util_verify_tx_start_enc(uint16_t conn_handle,
  *****************************************************************************/
 
 static void
-ble_l2cap_sm_test_util_peer_lgcy_good(
+ble_l2cap_sm_test_util_peer_fail_inval(
+    int we_are_master,
     uint8_t *init_addr,
     uint8_t *rsp_addr,
     struct ble_l2cap_sm_pair_cmd *pair_req,
-    struct ble_l2cap_sm_pair_cmd *pair_rsp,
-    struct ble_l2cap_sm_pair_confirm *confirm_req,
-    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)
+    struct ble_l2cap_sm_pair_fail *pair_fail)
 {
     struct ble_hs_conn *conn;
 
     ble_l2cap_sm_test_util_init();
     ble_hs_test_util_set_public_addr(rsp_addr);
-    ble_l2cap_sm_dbg_set_next_pair_rand(random_rsp->value);
 
     conn = ble_hs_test_util_create_conn(2, init_addr,
                                         ble_l2cap_sm_test_util_conn_cb,
                                         NULL);
 
-    /* Peer is the initiator so we must be the slave. */
-    conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
+    if (!we_are_master) {
+        conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
+    }
 
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
     /* Receive a pair request from the peer. */
-    ble_l2cap_sm_test_util_rx_pair_req(conn, pair_req);
+    ble_l2cap_sm_test_util_rx_pair_req(conn, pair_req,
+                                       BLE_HS_SM_US_ERR(pair_fail->reason));
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
-    /* Ensure we sent the expected pair response. */
+    /* Ensure we sent the expected pair fail. */
     ble_hs_test_util_tx_all();
-    ble_l2cap_sm_test_util_verify_tx_pair_rsp(pair_rsp);
+    ble_l2cap_sm_test_util_verify_tx_pair_fail(pair_fail);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
-    /* Receive a pair confirm from the peer. */
-    ble_l2cap_sm_test_util_rx_confirm(conn, confirm_req);
-    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+    /* Verify that security callback was not executed. */
+    TEST_ASSERT(ble_l2cap_sm_test_gap_event == -1);
+    TEST_ASSERT(ble_l2cap_sm_test_gap_status == -1);
 
-    /* Ensure we sent the expected pair confirm. */
-    ble_hs_test_util_tx_all();
-    ble_l2cap_sm_test_util_verify_tx_pair_confirm(confirm_rsp);
+    /* Verify that connection has correct security state. */
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+    TEST_ASSERT(!conn->bhc_sec_state.authenticated);
+}
 
-    /* Receive a pair random from the peer. */
-    ble_l2cap_sm_test_util_rx_random(conn, random_req, 0);
-    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+TEST_CASE(ble_l2cap_sm_test_case_peer_fail_inval)
+{
+    /* Invalid role detected before other arguments. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        1,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x14,
+            .oob_data_flag = 0,
+            .authreq = 0x12,
+            .max_enc_key_size = 20,
+            .init_key_dist = 0x0b,
+            .resp_key_dist = 0x11,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_CMD_NOT_SUPP,
+        } })
+    );
 
-    /* Ensure we sent the expected pair random. */
-    ble_hs_test_util_tx_all();
-    ble_l2cap_sm_test_util_verify_tx_pair_random(random_rsp);
-    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+    /* Invalid IO capabiltiies. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x14,
+            .oob_data_flag = 0,
+            .authreq = 0x05,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x07,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
 
-    /* Receive a long term key request from the controller. */
-    ble_l2cap_sm_test_util_set_lt_key_req_reply_ack(0, 2);
-    ble_l2cap_sm_test_util_rx_lt_key_req(2, r, ediv);
-    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+    /* Invalid OOB flag. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x04,
+            .oob_data_flag = 2,
+            .authreq = 0x05,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x07,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
 
-    /* Ensure we sent the expected long term key request reply command. */
-    ble_l2cap_sm_test_util_verify_tx_lt_key_req_reply(2, stk);
-    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+    /* Invalid authreq - reserved bonding flag. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x04,
+            .oob_data_flag = 0,
+            .authreq = 0x2,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x07,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
 
-    /* Receive an encryption changed event. */
-    ble_l2cap_sm_test_util_rx_enc_change(2, 0, 1);
+    /* Invalid authreq - reserved other flag. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x04,
+            .oob_data_flag = 0,
+            .authreq = 0x20,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x07,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
 
-    /* Pairing should now be complete. */
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
+    /* Invalid key size - too small. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x04,
+            .oob_data_flag = 0,
+            .authreq = 0x5,
+            .max_enc_key_size = 6,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x07,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
 
-    /* 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_state.pair_alg == pair_alg);
-    TEST_ASSERT(ble_l2cap_sm_test_sec_state.enc_enabled);
-    TEST_ASSERT(!ble_l2cap_sm_test_sec_state.authenticated);
+    /* Invalid key size - too large. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x04,
+            .oob_data_flag = 0,
+            .authreq = 0x5,
+            .max_enc_key_size = 17,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x07,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
 
-    /* Verify that connection has correct security state. */
-    TEST_ASSERT(ble_l2cap_sm_test_sec_state.pair_alg ==
-                conn->bhc_sec_state.pair_alg);
-    TEST_ASSERT(ble_l2cap_sm_test_sec_state.enc_enabled ==
-                conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_test_sec_state.authenticated ==
-                conn->bhc_sec_state.authenticated);
+    /* Invalid init key dist. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x04,
+            .oob_data_flag = 0,
+            .authreq = 0x5,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0x10,
+            .resp_key_dist = 0x07,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
+
+    /* Invalid resp key dist. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x04,
+            .oob_data_flag = 0,
+            .authreq = 0x5,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x10,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
 }
 
 static void
-ble_l2cap_sm_test_util_peer_lgcy_fail(
+ble_l2cap_sm_test_util_peer_lgcy_fail_confirm(
     uint8_t *init_addr,
     uint8_t *rsp_addr,
     struct ble_l2cap_sm_pair_cmd *pair_req,
@@ -517,7 +639,7 @@ ble_l2cap_sm_test_util_peer_lgcy_fail(
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
     /* Receive a pair request from the peer. */
-    ble_l2cap_sm_test_util_rx_pair_req(conn, pair_req);
+    ble_l2cap_sm_test_util_rx_pair_req(conn, pair_req, 0);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Ensure we sent the expected pair response. */
@@ -563,65 +685,9 @@ ble_l2cap_sm_test_util_peer_lgcy_fail(
                 conn->bhc_sec_state.authenticated);
 }
 
-TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_jw_good)
-{
-    ble_l2cap_sm_test_util_peer_lgcy_good(
-        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
-        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
-        ((struct ble_l2cap_sm_pair_cmd[1]) { {
-            .io_cap = 0x04,
-            .oob_data_flag = 0,
-            .authreq = 0x05,
-            .max_enc_key_size = 16,
-            .init_key_dist = 0x07,
-            .resp_key_dist = 0x07,
-        } }),
-        ((struct ble_l2cap_sm_pair_cmd[1]) { {
-            .io_cap = 3,
-            .oob_data_flag = 0,
-            .authreq = 0,
-            .max_enc_key_size = 16,
-            .init_key_dist = 0,
-            .resp_key_dist = 0,
-        } }),
-        ((struct ble_l2cap_sm_pair_confirm[1]) { {
-            .value = {
-                0x0a, 0xac, 0xa2, 0xae, 0xa6, 0x98, 0xdc, 0x6d,
-                0x65, 0x84, 0x11, 0x69, 0x47, 0x36, 0x8d, 0xa0,
-            },
-        } }),
-        ((struct ble_l2cap_sm_pair_confirm[1]) { {
-            .value = {
-                0x45, 0xd2, 0x2c, 0x38, 0xd8, 0x91, 0x4f, 0x19,
-                0xa2, 0xd4, 0xfc, 0x7d, 0xad, 0x37, 0x79, 0xe0
-            },
-        } }),
-        ((struct ble_l2cap_sm_pair_random[1]) { {
-            .value = {
-                0x2b, 0x3b, 0x69, 0xe4, 0xef, 0xab, 0xcc, 0x48,
-                0x78, 0x20, 0x1a, 0x54, 0x7a, 0x91, 0x5d, 0xfb,
-            },
-        } }),
-        ((struct ble_l2cap_sm_pair_random[1]) { {
-            .value = {
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-            },
-        } }),
-        BLE_L2CAP_SM_PAIR_ALG_JW,
-        NULL,
-        ((uint8_t[16]) {
-            0xa4, 0x8e, 0x51, 0x0d, 0x33, 0xe7, 0x8f, 0x38,
-            0x45, 0xf0, 0x67, 0xc3, 0xd4, 0x05, 0xb3, 0xe6,
-        }),
-        0,
-        0
-    );
-}
-
-TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_fail)
+TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_fail_confirm)
 {
-    ble_l2cap_sm_test_util_peer_lgcy_fail(
+    ble_l2cap_sm_test_util_peer_lgcy_fail_confirm(
         ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
         ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
         ((struct ble_l2cap_sm_pair_cmd[1]) { {
@@ -670,12 +736,8 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_fail)
     );
 }
 
-/*****************************************************************************
- * $us                                                                       *
- *****************************************************************************/
-
 static void
-ble_l2cap_sm_test_util_us_lgcy_good(
+ble_l2cap_sm_test_util_peer_lgcy_good(
     uint8_t *init_addr,
     uint8_t *rsp_addr,
     struct ble_l2cap_sm_pair_cmd *pair_req,
@@ -691,61 +753,62 @@ ble_l2cap_sm_test_util_us_lgcy_good(
     uint16_t ediv)
 {
     struct ble_hs_conn *conn;
-    int rc;
 
     ble_l2cap_sm_test_util_init();
-    ble_hs_test_util_set_public_addr(init_addr);
-    ble_l2cap_sm_dbg_set_next_pair_rand(random_req->value);
-    ble_l2cap_sm_dbg_set_next_ediv(ediv);
-    ble_l2cap_sm_dbg_set_next_start_rand(r);
+    ble_hs_test_util_set_public_addr(rsp_addr);
+    ble_l2cap_sm_dbg_set_next_pair_rand(random_rsp->value);
 
-    conn = ble_hs_test_util_create_conn(2, rsp_addr,
+    conn = ble_hs_test_util_create_conn(2, init_addr,
                                         ble_l2cap_sm_test_util_conn_cb,
                                         NULL);
 
+    /* Peer is the initiator so we must be the slave. */
+    conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
+
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
-    /* Initiate the pairing procedure. */
-    rc = ble_hs_test_util_security_initiate(2, 0);
-    TEST_ASSERT_FATAL(rc == 0);
+    /* Receive a pair request from the peer. */
+    ble_l2cap_sm_test_util_rx_pair_req(conn, pair_req, 0);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
-    /* Ensure we sent the expected pair request. */
+    /* Ensure we sent the expected pair response. */
     ble_hs_test_util_tx_all();
-    ble_l2cap_sm_test_util_verify_tx_pair_req(pair_req);
+    ble_l2cap_sm_test_util_verify_tx_pair_rsp(pair_rsp);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
-    /* Receive a pair response from the peer. */
-    ble_l2cap_sm_test_util_rx_pair_rsp(conn, pair_rsp);
+    /* Receive a pair confirm from the peer. */
+    ble_l2cap_sm_test_util_rx_confirm(conn, confirm_req);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Ensure we sent the expected pair confirm. */
     ble_hs_test_util_tx_all();
-    ble_l2cap_sm_test_util_verify_tx_pair_confirm(confirm_req);
+    ble_l2cap_sm_test_util_verify_tx_pair_confirm(confirm_rsp);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
-    /* Receive a pair confirm from the peer. */
-    ble_l2cap_sm_test_util_rx_confirm(conn, confirm_rsp);
+    /* Receive a pair random from the peer. */
+    ble_l2cap_sm_test_util_rx_random(conn, random_req, 0);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Ensure we sent the expected pair random. */
     ble_hs_test_util_tx_all();
-    ble_l2cap_sm_test_util_verify_tx_pair_random(random_req);
+    ble_l2cap_sm_test_util_verify_tx_pair_random(random_rsp);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
-    /* Receive a pair random from the peer. */
-    ble_l2cap_sm_test_util_rx_random(conn, random_rsp, 0);
+    /* Receive a long term key request from the controller. */
+    ble_l2cap_sm_test_util_set_lt_key_req_reply_ack(0, 2);
+    ble_l2cap_sm_test_util_rx_lt_key_req(2, r, ediv);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
-    /* Ensure we sent the expected start encryption command. */
-    ble_hs_test_util_tx_all();
-    ble_l2cap_sm_test_util_verify_tx_start_enc(2, r, ediv, stk);
+    /* Ensure we sent the expected long term key request reply command. */
+    ble_l2cap_sm_test_util_verify_tx_lt_key_req_reply(2, stk);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
@@ -771,18 +834,18 @@ ble_l2cap_sm_test_util_us_lgcy_good(
                 conn->bhc_sec_state.authenticated);
 }
 
-TEST_CASE(ble_l2cap_sm_test_case_us_lgcy_jw_good)
+TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_jw_good)
 {
-    ble_l2cap_sm_test_util_us_lgcy_good(
-        ((uint8_t[]){0x06, 0x05, 0x04, 0x03, 0x02, 0x01}),
-        ((uint8_t[]){0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a}),
+    ble_l2cap_sm_test_util_peer_lgcy_good(
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
         ((struct ble_l2cap_sm_pair_cmd[1]) { {
-            .io_cap = 3,
+            .io_cap = 0x04,
             .oob_data_flag = 0,
-            .authreq = 0,
+            .authreq = 0x05,
             .max_enc_key_size = 16,
-            .init_key_dist = 0,
-            .resp_key_dist = 0,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x07,
         } }),
         ((struct ble_l2cap_sm_pair_cmd[1]) { {
             .io_cap = 3,
@@ -794,20 +857,20 @@ TEST_CASE(ble_l2cap_sm_test_case_us_lgcy_jw_good)
         } }),
         ((struct ble_l2cap_sm_pair_confirm[1]) { {
             .value = {
-                0x04, 0x4e, 0xaf, 0xce, 0x30, 0x79, 0x2c, 0x9e,
-                0xa2, 0xeb, 0x53, 0x6a, 0xdf, 0xf7, 0x99, 0xb2,
+                0x0a, 0xac, 0xa2, 0xae, 0xa6, 0x98, 0xdc, 0x6d,
+                0x65, 0x84, 0x11, 0x69, 0x47, 0x36, 0x8d, 0xa0,
             },
         } }),
         ((struct ble_l2cap_sm_pair_confirm[1]) { {
             .value = {
-                0x04, 0x4e, 0xaf, 0xce, 0x30, 0x79, 0x2c, 0x9e,
-                0xa2, 0xeb, 0x53, 0x6a, 0xdf, 0xf7, 0x99, 0xb2,
+                0x45, 0xd2, 0x2c, 0x38, 0xd8, 0x91, 0x4f, 0x19,
+                0xa2, 0xd4, 0xfc, 0x7d, 0xad, 0x37, 0x79, 0xe0
             },
         } }),
         ((struct ble_l2cap_sm_pair_random[1]) { {
             .value = {
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x2b, 0x3b, 0x69, 0xe4, 0xef, 0xab, 0xcc, 0x48,
+                0x78, 0x20, 0x1a, 0x54, 0x7a, 0x91, 0x5d, 0xfb,
             },
         } }),
         ((struct ble_l2cap_sm_pair_random[1]) { {
@@ -819,8 +882,8 @@ TEST_CASE(ble_l2cap_sm_test_case_us_lgcy_jw_good)
         BLE_L2CAP_SM_PAIR_ALG_JW,
         NULL,
         ((uint8_t[16]) {
-            0x2e, 0x2b, 0x34, 0xca, 0x59, 0xfa, 0x4c, 0x88,
-            0x3b, 0x2c, 0x8a, 0xef, 0xd4, 0x4b, 0xe9, 0x66,
+            0xa4, 0x8e, 0x51, 0x0d, 0x33, 0xe7, 0x8f, 0x38,
+            0x45, 0xf0, 0x67, 0xc3, 0xd4, 0x05, 0xb3, 0xe6,
         }),
         0,
         0
@@ -946,10 +1009,168 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_bonding_bad)
     ble_l2cap_sm_test_util_peer_bonding_bad(54325, 65437);
 }
 
+/*****************************************************************************
+ * $us                                                                       *
+ *****************************************************************************/
+
+static void
+ble_l2cap_sm_test_util_us_lgcy_good(
+    uint8_t *init_addr,
+    uint8_t *rsp_addr,
+    struct ble_l2cap_sm_pair_cmd *pair_req,
+    struct ble_l2cap_sm_pair_cmd *pair_rsp,
+    struct ble_l2cap_sm_pair_confirm *confirm_req,
+    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)
+{
+    struct ble_hs_conn *conn;
+    int rc;
+
+    ble_l2cap_sm_test_util_init();
+    ble_hs_test_util_set_public_addr(init_addr);
+    ble_l2cap_sm_dbg_set_next_pair_rand(random_req->value);
+    ble_l2cap_sm_dbg_set_next_ediv(ediv);
+    ble_l2cap_sm_dbg_set_next_start_rand(r);
+
+    conn = ble_hs_test_util_create_conn(2, rsp_addr,
+                                        ble_l2cap_sm_test_util_conn_cb,
+                                        NULL);
+
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
+
+    /* Initiate the pairing procedure. */
+    rc = ble_hs_test_util_security_initiate(2, 0);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    /* Ensure we sent the expected pair request. */
+    ble_hs_test_util_tx_all();
+    ble_l2cap_sm_test_util_verify_tx_pair_req(pair_req);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+
+    /* Receive a pair response from the peer. */
+    ble_l2cap_sm_test_util_rx_pair_rsp(conn, pair_rsp, 0);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+
+    /* Ensure we sent the expected pair confirm. */
+    ble_hs_test_util_tx_all();
+    ble_l2cap_sm_test_util_verify_tx_pair_confirm(confirm_req);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+
+    /* Receive a pair confirm from the peer. */
+    ble_l2cap_sm_test_util_rx_confirm(conn, confirm_rsp);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+
+    /* Ensure we sent the expected pair random. */
+    ble_hs_test_util_tx_all();
+    ble_l2cap_sm_test_util_verify_tx_pair_random(random_req);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+
+    /* Receive a pair random from the peer. */
+    ble_l2cap_sm_test_util_rx_random(conn, random_rsp, 0);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+
+    /* Ensure we sent the expected start encryption command. */
+    ble_hs_test_util_tx_all();
+    ble_l2cap_sm_test_util_verify_tx_start_enc(2, r, ediv, stk);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+
+    /* Receive an encryption changed event. */
+    ble_l2cap_sm_test_util_rx_enc_change(2, 0, 1);
+
+    /* Pairing should now be complete. */
+    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_state.pair_alg == pair_alg);
+    TEST_ASSERT(ble_l2cap_sm_test_sec_state.enc_enabled);
+    TEST_ASSERT(!ble_l2cap_sm_test_sec_state.authenticated);
+
+    /* Verify that connection has correct security state. */
+    TEST_ASSERT(ble_l2cap_sm_test_sec_state.pair_alg ==
+                conn->bhc_sec_state.pair_alg);
+    TEST_ASSERT(ble_l2cap_sm_test_sec_state.enc_enabled ==
+                conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_test_sec_state.authenticated ==
+                conn->bhc_sec_state.authenticated);
+}
+
+TEST_CASE(ble_l2cap_sm_test_case_us_lgcy_jw_good)
+{
+    ble_l2cap_sm_test_util_us_lgcy_good(
+        ((uint8_t[]){0x06, 0x05, 0x04, 0x03, 0x02, 0x01}),
+        ((uint8_t[]){0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 3,
+            .oob_data_flag = 0,
+            .authreq = 0,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0,
+            .resp_key_dist = 0,
+        } }),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 3,
+            .oob_data_flag = 0,
+            .authreq = 0,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0,
+            .resp_key_dist = 0,
+        } }),
+        ((struct ble_l2cap_sm_pair_confirm[1]) { {
+            .value = {
+                0x04, 0x4e, 0xaf, 0xce, 0x30, 0x79, 0x2c, 0x9e,
+                0xa2, 0xeb, 0x53, 0x6a, 0xdf, 0xf7, 0x99, 0xb2,
+            },
+        } }),
+        ((struct ble_l2cap_sm_pair_confirm[1]) { {
+            .value = {
+                0x04, 0x4e, 0xaf, 0xce, 0x30, 0x79, 0x2c, 0x9e,
+                0xa2, 0xeb, 0x53, 0x6a, 0xdf, 0xf7, 0x99, 0xb2,
+            },
+        } }),
+        ((struct ble_l2cap_sm_pair_random[1]) { {
+            .value = {
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            },
+        } }),
+        ((struct ble_l2cap_sm_pair_random[1]) { {
+            .value = {
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            },
+        } }),
+        BLE_L2CAP_SM_PAIR_ALG_JW,
+        NULL,
+        ((uint8_t[16]) {
+            0x2e, 0x2b, 0x34, 0xca, 0x59, 0xfa, 0x4c, 0x88,
+            0x3b, 0x2c, 0x8a, 0xef, 0xd4, 0x4b, 0xe9, 0x66,
+        }),
+        0,
+        0
+    );
+}
+
 TEST_SUITE(ble_l2cap_sm_test_suite)
 {
+    ble_l2cap_sm_test_case_peer_fail_inval();
+    ble_l2cap_sm_test_case_peer_lgcy_fail_confirm();
     ble_l2cap_sm_test_case_peer_lgcy_jw_good();
-    ble_l2cap_sm_test_case_peer_lgcy_fail();
     ble_l2cap_sm_test_case_us_lgcy_jw_good();
     ble_l2cap_sm_test_case_peer_bonding_good();
     ble_l2cap_sm_test_case_peer_bonding_bad();
@@ -962,6 +1183,7 @@ ble_l2cap_sm_test_all(void)
 #if !NIMBLE_OPT_SM
     return 0;
 #else
+    tu_config.tc_system_assert=1;
     ble_l2cap_sm_test_suite();
 
     return tu_any_failed;