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/17 20:52:04 UTC
[41/50] [abbrv] incubator-mynewt-core git commit: BLE Host - tx slave
security request.
BLE Host - tx slave security request.
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/26eef9af
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/26eef9af
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/26eef9af
Branch: refs/heads/master
Commit: 26eef9af3409225c2da26830cc9da2fd2375754c
Parents: 91e8101
Author: Christopher Collins <cc...@apache.org>
Authored: Mon May 16 19:46:49 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Mon May 16 19:47:13 2016 -0700
----------------------------------------------------------------------
net/nimble/host/src/ble_gap.c | 11 +-
net/nimble/host/src/ble_l2cap_sm.c | 177 ++++++++++++------
net/nimble/host/src/ble_l2cap_sm_priv.h | 3 +
net/nimble/host/src/test/ble_l2cap_sm_test.c | 218 ++++++++++++++++++++--
4 files changed, 337 insertions(+), 72 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/26eef9af/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 b43535c..5dc3078 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -1984,11 +1984,16 @@ ble_gap_security_initiate(uint16_t conn_handle)
return rc;
}
- if (!(conn_flags & BLE_HS_CONN_F_MASTER)) {
- return BLE_HS_EROLE;
+ if (conn_flags & BLE_HS_CONN_F_MASTER) {
+ /* XXX: Search the security database for an LTK for this peer. If one
+ * is found, perform the encryption procedure rather than the pairing
+ * procedure.
+ */
+ rc = ble_l2cap_sm_pair_initiate(conn_handle);
+ } else {
+ rc = ble_l2cap_sm_slave_initiate(conn_handle);
}
- rc = ble_l2cap_sm_pair_initiate(conn_handle);
return rc;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/26eef9af/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 05adfca..198f4fa 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -58,7 +58,8 @@
#define BLE_L2CAP_SM_PROC_STATE_LTK 3
#define BLE_L2CAP_SM_PROC_STATE_ENC_CHANGE 4
#define BLE_L2CAP_SM_PROC_STATE_KEY_EXCH 5
-#define BLE_L2CAP_SM_PROC_STATE_CNT 6
+#define BLE_L2CAP_SM_PROC_STATE_SEC_REQ 6
+#define BLE_L2CAP_SM_PROC_STATE_CNT 7
#define BLE_L2CAP_SM_PROC_F_INITIATOR 0x01
#define BLE_L2CAP_SM_PROC_F_TK_VALID 0x02
@@ -144,6 +145,7 @@ static int ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc,
uint8_t *pres, uint8_t *iat,
uint8_t *rat, uint8_t *ia,
uint8_t *ra);
+static void ble_l2cap_sm_check_key_exchange(struct ble_l2cap_sm_proc *proc);
/*****************************************************************************
@@ -538,6 +540,15 @@ ble_l2cap_sm_rx_noop(uint16_t conn_handle, uint8_t op, struct os_mbuf **om)
return BLE_HS_ENOTSUP;
}
+uint8_t
+ble_l2cap_sm_build_authreq(void)
+{
+ return ble_hs_cfg.sm_bonding << 0 |
+ ble_hs_cfg.sm_mitm << 2 |
+ ble_hs_cfg.sm_sc << 3 |
+ ble_hs_cfg.sm_keypress << 4;
+}
+
/*****************************************************************************
* $hci *
*****************************************************************************/
@@ -765,22 +776,22 @@ ble_l2cap_sm_random_handle(struct ble_l2cap_sm_proc *proc,
*/
static const uint8_t initiator_pkact[5 /*init*/ ][5 /*resp */] =
{
- {PKACT_NONE, PKACT_NONE, PKACT_INPUT, PKACT_NONE, PKACT_INPUT},
- {PKACT_NONE, PKACT_NONE, PKACT_INPUT, PKACT_NONE, PKACT_INPUT},
- {PKACT_DISP, PKACT_DISP, PKACT_INPUT, PKACT_NONE, PKACT_DISP},
- {PKACT_NONE, PKACT_NONE, PKACT_NONE, PKACT_NONE, PKACT_NONE},
- {PKACT_DISP, PKACT_DISP, PKACT_DISP, PKACT_NONE, PKACT_DISP},
+ {PKACT_NONE, PKACT_NONE, PKACT_INPUT, PKACT_NONE, PKACT_INPUT},
+ {PKACT_NONE, PKACT_NONE, PKACT_INPUT, PKACT_NONE, PKACT_INPUT},
+ {PKACT_DISP, PKACT_DISP, PKACT_INPUT, PKACT_NONE, PKACT_DISP},
+ {PKACT_NONE, PKACT_NONE, PKACT_NONE, PKACT_NONE, PKACT_NONE},
+ {PKACT_DISP, PKACT_DISP, PKACT_DISP, PKACT_NONE, PKACT_DISP},
};
/* This is the initiator passkey action action depending on the io
* capabilities of both parties */
static const uint8_t responder_pkact[5 /*init*/ ][5 /*resp */] =
{
- {PKACT_NONE, PKACT_NONE, PKACT_DISP, PKACT_NONE, PKACT_DISP},
- {PKACT_NONE, PKACT_NONE, PKACT_DISP, PKACT_NONE, PKACT_DISP},
- {PKACT_INPUT, PKACT_INPUT, PKACT_INPUT, PKACT_NONE, PKACT_INPUT},
- {PKACT_NONE, PKACT_NONE, PKACT_NONE, PKACT_NONE, PKACT_NONE},
- {PKACT_INPUT, PKACT_INPUT, PKACT_INPUT, PKACT_NONE, PKACT_INPUT},
+ {PKACT_NONE, PKACT_NONE, PKACT_DISP, PKACT_NONE, PKACT_DISP},
+ {PKACT_NONE, PKACT_NONE, PKACT_DISP, PKACT_NONE, PKACT_DISP},
+ {PKACT_INPUT, PKACT_INPUT, PKACT_INPUT, PKACT_NONE, PKACT_INPUT},
+ {PKACT_NONE, PKACT_NONE, PKACT_NONE, PKACT_NONE, PKACT_NONE},
+ {PKACT_INPUT, PKACT_INPUT, PKACT_INPUT, PKACT_NONE, PKACT_INPUT},
};
static int
@@ -957,10 +968,7 @@ ble_l2cap_sm_pair_go(struct ble_l2cap_sm_proc *proc)
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.authreq = ble_l2cap_sm_build_authreq();
cmd.max_enc_key_size = 16;
if (is_req) {
@@ -992,39 +1000,6 @@ ble_l2cap_sm_pair_go(struct ble_l2cap_sm_proc *proc)
return 0;
}
-static void
-ble_l2cap_sm_check_key_exchange(struct ble_l2cap_sm_proc *proc)
-{
- uint8_t rx_key_dist;
-
- if (proc->pair_req.authreq & BLE_L2CAP_SM_PAIR_AUTHREQ_BOND &&
- proc->pair_rsp.authreq & BLE_L2CAP_SM_PAIR_AUTHREQ_BOND &&
- proc->pair_rsp.init_key_dist &&
- proc->pair_rsp.resp_key_dist) {
-
- proc->flags |= BLE_L2CAP_SM_PROC_F_KEY_EXCHANGE;
- }
-
- if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
- rx_key_dist = proc->pair_rsp.resp_key_dist;
- } else {
- rx_key_dist = proc->pair_rsp.init_key_dist;
- }
-
- proc->rx_key_flags = 0;
- if (rx_key_dist & BLE_L2CAP_SM_PAIR_KEY_DIST_ENC) {
- proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_ENC_INFO |
- BLE_L2CAP_SM_KE_F_MASTER_IDEN;
- }
- if (rx_key_dist & BLE_L2CAP_SM_PAIR_KEY_DIST_ID) {
- proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_IDEN_INFO |
- BLE_L2CAP_SM_KE_F_ADDR_INFO;
- }
- if (rx_key_dist & BLE_L2CAP_SM_PAIR_KEY_DIST_SIGN) {
- proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_SIGN_INFO;
- }
-}
-
static int
ble_l2cap_sm_pair_req_handle(struct ble_l2cap_sm_proc *proc,
struct ble_l2cap_sm_pair_cmd *req,
@@ -1098,10 +1073,64 @@ ble_l2cap_sm_pair_rsp_handle(struct ble_l2cap_sm_proc *proc,
}
/*****************************************************************************
+ * $security request *
+ *****************************************************************************/
+
+static int
+ble_l2cap_sm_sec_req_go(struct ble_l2cap_sm_proc *proc)
+{
+ struct ble_l2cap_sm_sec_req cmd;
+ int rc;
+
+ cmd.authreq = ble_l2cap_sm_build_authreq();
+ rc = ble_l2cap_sm_sec_req_tx(proc->conn_handle, &cmd);
+ if (rc != 0) {
+ return rc;
+ }
+
+ ble_l2cap_sm_proc_set_timer(proc);
+
+ return 0;
+}
+
+/*****************************************************************************
* $key exchange *
*****************************************************************************/
static void
+ble_l2cap_sm_check_key_exchange(struct ble_l2cap_sm_proc *proc)
+{
+ uint8_t rx_key_dist;
+
+ if (proc->pair_req.authreq & BLE_L2CAP_SM_PAIR_AUTHREQ_BOND &&
+ proc->pair_rsp.authreq & BLE_L2CAP_SM_PAIR_AUTHREQ_BOND &&
+ proc->pair_rsp.init_key_dist &&
+ proc->pair_rsp.resp_key_dist) {
+
+ proc->flags |= BLE_L2CAP_SM_PROC_F_KEY_EXCHANGE;
+ }
+
+ if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
+ rx_key_dist = proc->pair_rsp.resp_key_dist;
+ } else {
+ rx_key_dist = proc->pair_rsp.init_key_dist;
+ }
+
+ proc->rx_key_flags = 0;
+ if (rx_key_dist & BLE_L2CAP_SM_PAIR_KEY_DIST_ENC) {
+ proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_ENC_INFO |
+ BLE_L2CAP_SM_KE_F_MASTER_IDEN;
+ }
+ if (rx_key_dist & BLE_L2CAP_SM_PAIR_KEY_DIST_ID) {
+ proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_IDEN_INFO |
+ BLE_L2CAP_SM_KE_F_ADDR_INFO;
+ }
+ if (rx_key_dist & BLE_L2CAP_SM_PAIR_KEY_DIST_SIGN) {
+ proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_SIGN_INFO;
+ }
+}
+
+static void
ble_l2cap_sm_enc_info_handle(struct ble_l2cap_sm_proc *proc,
struct ble_l2cap_sm_enc_info *info)
{
@@ -1662,10 +1691,10 @@ ble_l2cap_sm_rx_lt_key_req(struct hci_le_lt_key_req *evt)
proc = ble_l2cap_sm_proc_find(evt->connection_handle,
BLE_L2CAP_SM_PROC_STATE_NONE, 0, &prev);
if (proc == NULL) {
- /* The peer is attempting to restore a encrypted connection via
- * bonding. Create a proc entry to indicate that security
- * establishment is in progress and execute the procedure after the
- * mutex gets unlocked.
+ /* The peer is attempting to restore a encrypted connection via the
+ * encryption procedure (bonding). Create a proc entry to indicate
+ * that security establishment is in progress and execute the procedure
+ * after the mutex gets unlocked.
*/
bonding = 1;
proc = ble_l2cap_sm_proc_alloc();
@@ -1675,6 +1704,13 @@ ble_l2cap_sm_rx_lt_key_req(struct hci_le_lt_key_req *evt)
proc->flags |= BLE_L2CAP_SM_PROC_F_BONDED;
ble_l2cap_sm_insert(proc);
}
+ } else if (proc->state == BLE_L2CAP_SM_PROC_STATE_SEC_REQ) {
+ /* Same as above, except we solicited the encryption procedure by
+ * sending a security request.
+ */
+ bonding = 1;
+ proc->state = BLE_L2CAP_SM_PROC_STATE_LTK;
+ proc->flags |= BLE_L2CAP_SM_PROC_F_BONDED;
} else if (proc->state == BLE_L2CAP_SM_PROC_STATE_LTK) {
/* Short-term key pairing just completed. Send the short term key to
* the controller.
@@ -1906,6 +1942,43 @@ done:
return rc;
}
+int
+ble_l2cap_sm_slave_initiate(uint16_t conn_handle)
+{
+ struct ble_l2cap_sm_proc *proc;
+ int rc;
+
+ ble_hs_lock();
+
+ /* Make sure 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;
+ goto done;
+ }
+
+ proc = ble_l2cap_sm_proc_alloc();
+ if (proc == NULL) {
+ rc = BLE_HS_ENOMEM;
+ goto done;
+ }
+ proc->conn_handle = conn_handle;
+ proc->state = BLE_L2CAP_SM_PROC_STATE_SEC_REQ;
+
+ rc = ble_l2cap_sm_sec_req_go(proc);
+ if (rc != 0) {
+ ble_l2cap_sm_proc_free(proc);
+ goto done;
+ }
+
+ ble_l2cap_sm_insert(proc);
+
+done:
+ ble_hs_unlock();
+ return rc;
+}
+
/**
* Initiates the encryption procedure for the specified connection.
*/
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/26eef9af/net/nimble/host/src/ble_l2cap_sm_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm_priv.h b/net/nimble/host/src/ble_l2cap_sm_priv.h
index 99070dc..09a4a53 100644
--- a/net/nimble/host/src/ble_l2cap_sm_priv.h
+++ b/net/nimble/host/src/ble_l2cap_sm_priv.h
@@ -163,6 +163,8 @@ void ble_l2cap_sm_dbg_set_next_ltk(uint8_t *next_ltk);
int ble_l2cap_sm_dbg_num_procs(void);
#endif
+uint8_t ble_l2cap_sm_build_authreq(void);
+
struct ble_l2cap_chan *ble_l2cap_sm_create_chan(void);
void ble_l2cap_sm_pair_cmd_parse(void *payload, int len,
@@ -229,6 +231,7 @@ int ble_l2cap_sm_rx_lt_key_req(struct hci_le_lt_key_req *evt);
void ble_l2cap_sm_heartbeat(void);
int ble_l2cap_sm_pair_initiate(uint16_t conn_handle);
+int ble_l2cap_sm_slave_initiate(uint16_t conn_handle);
int ble_l2cap_sm_enc_initiate(uint16_t conn_handle, uint8_t *ltk,
uint16_t ediv, uint64_t rand_val, int auth);
int ble_l2cap_sm_init(void);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/26eef9af/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 5e3dce9..a775cd5 100644
--- a/net/nimble/host/src/test/ble_l2cap_sm_test.c
+++ b/net/nimble/host/src/test/ble_l2cap_sm_test.c
@@ -6,7 +6,7 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
@@ -41,6 +41,7 @@ struct ble_gap_ltk_params ble_l2cap_sm_test_ltk_params;
struct ble_l2cap_sm_test_pair_params {
uint8_t init_addr[6];
uint8_t rsp_addr[6];
+ struct ble_l2cap_sm_sec_req sec_req;
struct ble_l2cap_sm_pair_cmd pair_req;
struct ble_l2cap_sm_pair_cmd pair_rsp;
struct ble_l2cap_sm_pair_confirm confirm_req;
@@ -61,6 +62,7 @@ struct ble_l2cap_sm_test_pair_params {
struct ble_l2cap_sm_passkey passkey;
struct ble_l2cap_sm_pair_fail pair_fail;
+ unsigned has_sec_req:1;
unsigned has_enc_info_req:1;
unsigned has_enc_info_rsp:1;
unsigned has_master_id_req:1;
@@ -834,6 +836,7 @@ ble_l2cap_sm_test_util_peer_lgcy_good(
struct ble_l2cap_sm_test_pair_params *params)
{
struct ble_hs_conn *conn;
+ int rc;
ble_l2cap_sm_test_util_init();
@@ -871,6 +874,11 @@ ble_l2cap_sm_test_util_peer_lgcy_good(
TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
+ if (params->has_sec_req) {
+ rc = ble_l2cap_sm_slave_initiate(2);
+ TEST_ASSERT(rc == 0);
+ }
+
/* Receive a pair request from the peer. */
ble_l2cap_sm_test_util_rx_pair_req(2, ¶ms->pair_req, 0);
TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
@@ -1066,12 +1074,20 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_passkey_good)
ble_l2cap_sm_test_util_peer_lgcy_good(¶ms);
}
+/**
+ * @param send_enc_req Whether this procedure is initiated by a slave
+ * security request;
+ * 1: We send a security request at start.
+ * 0: No security request; peer initiates.
+ */
static void
-ble_l2cap_sm_test_util_peer_bonding_good(uint8_t *ltk, int authenticated,
+ble_l2cap_sm_test_util_peer_bonding_good(int send_enc_req, uint8_t *ltk,
+ int authenticated,
uint16_t ediv, uint64_t rand_num)
{
struct ble_l2cap_sm_test_ltk_info ltk_info;
struct ble_hs_conn *conn;
+ int rc;
ble_l2cap_sm_test_util_init();
@@ -1094,6 +1110,11 @@ ble_l2cap_sm_test_util_peer_bonding_good(uint8_t *ltk, int authenticated,
TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
+ if (send_enc_req) {
+ rc = ble_l2cap_sm_slave_initiate(2);
+ TEST_ASSERT(rc == 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, rand_num, ediv);
@@ -1184,6 +1205,7 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_bonding_good)
{
/* Unauthenticated. */
ble_l2cap_sm_test_util_peer_bonding_good(
+ 0,
((uint8_t[16]){ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }),
0,
0x1234,
@@ -1191,6 +1213,7 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_bonding_good)
/* Authenticated. */
ble_l2cap_sm_test_util_peer_bonding_good(
+ 0,
((uint8_t[16]){ 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 }),
1,
0x4325,
@@ -1510,9 +1533,15 @@ ble_l2cap_sm_test_util_us_lgcy_good(
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);
+ ble_hs_test_util_set_ack(
+ host_hci_opcode_join(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_START_ENCRYPT), 0);
+ if (params->has_sec_req) {
+ ble_l2cap_sm_test_util_rx_sec_req(2, ¶ms->sec_req, 0);
+ } else {
+ /* Initiate the pairing procedure. */
+ rc = ble_gap_security_initiate(2);
+ TEST_ASSERT_FATAL(rc == 0);
+ }
/* Ensure we sent the expected pair request. */
ble_hs_test_util_tx_all();
@@ -1586,7 +1615,7 @@ TEST_CASE(ble_l2cap_sm_test_case_us_lgcy_jw_good)
struct ble_l2cap_sm_test_pair_params params;
params = (struct ble_l2cap_sm_test_pair_params) {
- .init_addr = {0x06, 0x05, 0x04, 0x03, 0x02, 0x01},
+ .init_addr = {0x06, 0x05, 0x04, 0x03, 0x02, 0x01},
.rsp_addr = {0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a},
.pair_req = (struct ble_l2cap_sm_pair_cmd) {
.io_cap = 3,
@@ -1672,7 +1701,6 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_sec_req_inval)
{
struct ble_l2cap_sm_pair_fail fail;
struct ble_l2cap_sm_sec_req sec_req;
- struct ble_hs_conn *conn;
int rc;
ble_l2cap_sm_test_util_init();
@@ -1681,17 +1709,8 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_sec_req_inval)
ble_l2cap_sm_test_util_conn_cb,
NULL);
- /* This test inspects and modifies the connection object without locking
- * the host mutex. It is not OK for real code to do this, but this test
- * can assume the connection list is unchanging.
- */
- ble_hs_lock();
- conn = ble_hs_conn_find(2);
- TEST_ASSERT_FATAL(conn != NULL);
- ble_hs_unlock();
-
/*** We are the slave; reject the security request. */
- conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
+ ble_hs_atomic_conn_set_flags(2, BLE_HS_CONN_F_MASTER, 0);
sec_req.authreq = 0;
ble_l2cap_sm_test_util_rx_sec_req(
@@ -1713,6 +1732,167 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_sec_req_inval)
TEST_ASSERT(ble_hs_test_util_prev_tx_queue_sz() == 0);
}
+/**
+ * Master: us.
+ * Peer sends a security request.
+ * We respond by initiating the pairing procedure.
+ */
+TEST_CASE(ble_l2cap_sm_test_case_peer_sec_req_pair)
+{
+ struct ble_l2cap_sm_test_pair_params params;
+
+ params = (struct ble_l2cap_sm_test_pair_params) {
+ .init_addr = {0x06, 0x05, 0x04, 0x03, 0x02, 0x01},
+ .rsp_addr = {0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a},
+ .sec_req = (struct ble_l2cap_sm_sec_req) {
+ .authreq = 0,
+ },
+ .has_sec_req = 1,
+ .pair_req = (struct ble_l2cap_sm_pair_cmd) {
+ .io_cap = 3,
+ .oob_data_flag = 0,
+ .authreq = 0,
+ .max_enc_key_size = 16,
+ .init_key_dist = 0,
+ .resp_key_dist = 0,
+ },
+ .pair_rsp = (struct ble_l2cap_sm_pair_cmd) {
+ .io_cap = 3,
+ .oob_data_flag = 0,
+ .authreq = 0,
+ .max_enc_key_size = 16,
+ .init_key_dist = 0,
+ .resp_key_dist = 0,
+ },
+ .confirm_req = (struct ble_l2cap_sm_pair_confirm) {
+ .value = {
+ 0x04, 0x4e, 0xaf, 0xce, 0x30, 0x79, 0x2c, 0x9e,
+ 0xa2, 0xeb, 0x53, 0x6a, 0xdf, 0xf7, 0x99, 0xb2,
+ },
+ },
+ .confirm_rsp = (struct ble_l2cap_sm_pair_confirm) {
+ .value = {
+ 0x04, 0x4e, 0xaf, 0xce, 0x30, 0x79, 0x2c, 0x9e,
+ 0xa2, 0xeb, 0x53, 0x6a, 0xdf, 0xf7, 0x99, 0xb2,
+ },
+ },
+ .random_req = (struct ble_l2cap_sm_pair_random) {
+ .value = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ },
+ .random_rsp = (struct ble_l2cap_sm_pair_random) {
+ .value = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ },
+ .pair_alg = BLE_L2CAP_SM_PAIR_ALG_JW,
+ .tk = { 0 },
+ .stk = {
+ 0x2e, 0x2b, 0x34, 0xca, 0x59, 0xfa, 0x4c, 0x88,
+ 0x3b, 0x2c, 0x8a, 0xef, 0xd4, 0x4b, 0xe9, 0x66,
+ },
+ .r = 0,
+ .ediv = 0,
+ };
+
+ ble_l2cap_sm_test_util_us_lgcy_good(¶ms);
+}
+
+/**
+ * Master: peer.
+ * We send a security request.
+ * We accept pairing request sent in response.
+ */
+TEST_CASE(ble_l2cap_sm_test_case_us_sec_req_pair)
+{
+ struct ble_l2cap_sm_test_pair_params params;
+
+ params = (struct ble_l2cap_sm_test_pair_params) {
+ .init_addr = {0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c},
+ .rsp_addr = {0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07},
+ .sec_req = (struct ble_l2cap_sm_sec_req) {
+ .authreq = 0x05,
+ },
+ .has_sec_req = 1,
+ .pair_req = (struct ble_l2cap_sm_pair_cmd) {
+ .io_cap = 0x04,
+ .oob_data_flag = 0,
+ .authreq = 0x05,
+ .max_enc_key_size = 16,
+ .init_key_dist = 0x07,
+ .resp_key_dist = 0x07,
+ },
+ .pair_rsp = (struct ble_l2cap_sm_pair_cmd) {
+ .io_cap = 0x02,
+ .oob_data_flag = 0,
+ .authreq = 0x05,
+ .max_enc_key_size = 16,
+ .init_key_dist = 0x01,
+ .resp_key_dist = 0x01,
+ },
+ .confirm_req = (struct ble_l2cap_sm_pair_confirm) {
+ .value = {
+ 0x54, 0xed, 0x7c, 0x65, 0xc5, 0x3a, 0xee, 0x87,
+ 0x8e, 0xf8, 0x04, 0xd8, 0x93, 0xb0, 0xfa, 0xa4,
+ },
+ },
+ .confirm_rsp = (struct ble_l2cap_sm_pair_confirm) {
+ .value = {
+ 0xdf, 0x96, 0x88, 0x73, 0x49, 0x24, 0x3f, 0xe8,
+ 0xb0, 0xaf, 0xb3, 0xf6, 0xc8, 0xf4, 0xe2, 0x36,
+ },
+ },
+ .random_req = (struct ble_l2cap_sm_pair_random) {
+ .value = {
+ 0x4d, 0x2c, 0xf2, 0xb7, 0x11, 0x56, 0xbd, 0x4f,
+ 0xfc, 0xde, 0xa9, 0x86, 0x4d, 0xfd, 0x77, 0x03,
+ },
+ },
+ .random_rsp = {
+ .value = {
+ 0x12, 0x45, 0x65, 0x2c, 0x85, 0x56, 0x32, 0x8f,
+ 0xf4, 0x7f, 0x44, 0xd0, 0x17, 0x35, 0x41, 0xed
+ },
+ },
+ .pair_alg = BLE_L2CAP_SM_PAIR_ALG_PASSKEY,
+ .authenticated = 1,
+ .tk = {
+ 0x5a, 0x7f, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .stk = {
+ 0x2b, 0x9c, 0x1e, 0x42, 0xa8, 0xcb, 0xab, 0xd1,
+ 0x4b, 0xde, 0x50, 0x05, 0x50, 0xd9, 0x95, 0xc6
+ },
+ .r = 4107344270811490869,
+ .ediv = 61621,
+
+ .passkey = {
+ .action = BLE_GAP_PKACT_INPUT,
+ .passkey = 884570,
+ }
+ };
+ ble_l2cap_sm_test_util_peer_lgcy_good(¶ms);
+}
+
+/**
+ * Master: peer.
+ * We send a security request.
+ * We accept an encryption-changed event in response.
+ */
+TEST_CASE(ble_l2cap_sm_test_case_us_sec_req_enc)
+{
+ ble_l2cap_sm_test_util_peer_bonding_good(
+ 1,
+ ((uint8_t[16]){ 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 }),
+ 1,
+ 0x4325,
+ 0x543892375);
+}
+
TEST_SUITE(ble_l2cap_sm_test_suite)
{
ble_l2cap_sm_test_case_peer_fail_inval();
@@ -1725,6 +1905,10 @@ TEST_SUITE(ble_l2cap_sm_test_suite)
ble_l2cap_sm_test_case_peer_bonding_bad();
ble_l2cap_sm_test_case_conn_broken();
ble_l2cap_sm_test_case_peer_sec_req_inval();
+ ble_l2cap_sm_test_case_peer_sec_req_pair();
+ /* XXX: ble_l2cap_sm_test_case_peer_sec_req_enc(); */
+ ble_l2cap_sm_test_case_us_sec_req_pair();
+ ble_l2cap_sm_test_case_us_sec_req_enc();
}
#endif