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 02:47:34 UTC
[1/4] incubator-mynewt-core git commit: BLE Host - Add bonded flag to
SM proc.
Repository: incubator-mynewt-core
Updated Branches:
refs/heads/develop 4d5aa14f6 -> 26eef9af3
BLE Host - Add bonded flag to SM proc.
This is needed so that the host/app/someone can determine if the
persisted client characteristic configuration should be restored upon
receiving an encryption-change HCI event.
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/28327e94
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/28327e94
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/28327e94
Branch: refs/heads/develop
Commit: 28327e946faebd02fee3913e175c01df2cbd7bac
Parents: aeb46ab
Author: Christopher Collins <cc...@apache.org>
Authored: Mon May 16 13:06:04 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Mon May 16 19:47:00 2016 -0700
----------------------------------------------------------------------
net/nimble/host/include/host/ble_gap.h | 1 +
net/nimble/host/src/ble_l2cap_sm.c | 7 +++++++
2 files changed, 8 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/28327e94/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 ef9a478..d3fc26d 100644
--- a/net/nimble/host/include/host/ble_gap.h
+++ b/net/nimble/host/include/host/ble_gap.h
@@ -105,6 +105,7 @@ struct ble_gap_sec_state {
uint8_t pair_alg;
unsigned enc_enabled:1;
unsigned authenticated:1;
+ unsigned bonded:1;
};
struct ble_gap_conn_desc {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/28327e94/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 a8fe98f..9703519 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -65,6 +65,7 @@
#define BLE_L2CAP_SM_PROC_F_RX_CONFIRM 0x04
#define BLE_L2CAP_SM_PROC_F_AUTHENTICATED 0x08
#define BLE_L2CAP_SM_PROC_F_KEY_EXCHANGE 0x10
+#define BLE_L2CAP_SM_PROC_F_BONDED 0x20
#define BLE_L2CAP_SM_KE_F_ENC_INFO 0x01
#define BLE_L2CAP_SM_KE_F_MASTER_IDEN 0x02
@@ -393,6 +394,7 @@ ble_l2cap_sm_sec_state(struct ble_l2cap_sm_proc *proc,
out_sec_state->enc_enabled = enc_enabled;
out_sec_state->authenticated =
(proc->flags & BLE_L2CAP_SM_PROC_F_AUTHENTICATED) ? 1 : 0;
+ out_sec_state->bonded = (proc->flags & BLE_L2CAP_SM_PROC_F_BONDED) ? 1 : 0;
}
static void
@@ -1331,6 +1333,10 @@ ble_l2cap_sm_rx_key_exchange(uint16_t conn_handle, uint8_t op,
rc = BLE_HS_ENOENT;
}
+ if (rc == 0 && sm_end) {
+ proc->flags |= BLE_L2CAP_SM_PROC_F_BONDED;
+ }
+
ble_hs_unlock();
/* a successful ending of the link */
@@ -1665,6 +1671,7 @@ ble_l2cap_sm_rx_lt_key_req(struct hci_le_lt_key_req *evt)
if (proc != NULL) {
proc->conn_handle = evt->connection_handle;
proc->state = BLE_L2CAP_SM_PROC_STATE_LTK;
+ proc->flags |= BLE_L2CAP_SM_PROC_F_BONDED;
ble_l2cap_sm_insert(proc);
}
} else if (proc->state == BLE_L2CAP_SM_PROC_STATE_LTK) {
[2/4] incubator-mynewt-core git commit: BLE Host - Rename sec procs
to match spec language
Posted by cc...@apache.org.
BLE Host - Rename sec procs to match spec language
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/aeb46aba
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/aeb46aba
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/aeb46aba
Branch: refs/heads/develop
Commit: aeb46abade038e6b62b0b7603455e8e8eda01bac
Parents: 4d5aa14
Author: Christopher Collins <cc...@apache.org>
Authored: Mon May 16 13:03:26 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Mon May 16 19:47:00 2016 -0700
----------------------------------------------------------------------
net/nimble/host/src/ble_gap.c | 5 ++---
net/nimble/host/src/ble_l2cap_sm.c | 19 ++++++++++---------
net/nimble/host/src/ble_l2cap_sm_priv.h | 4 ++--
3 files changed, 14 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/aeb46aba/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 14c921a..b43535c 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -816,7 +816,6 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt)
}
/* We verified that there is a free connection when the procedure began. */
- /* XXX: Revisit this; ensure this is guaranteed. */
conn = ble_hs_conn_alloc();
BLE_HS_DBG_ASSERT(conn != NULL);
@@ -1989,7 +1988,7 @@ ble_gap_security_initiate(uint16_t conn_handle)
return BLE_HS_EROLE;
}
- rc = ble_l2cap_sm_initiate(conn_handle);
+ rc = ble_l2cap_sm_pair_initiate(conn_handle);
return rc;
}
@@ -2012,7 +2011,7 @@ ble_gap_encryption_initiate(uint16_t conn_handle,
return BLE_HS_EROLE;
}
- rc = ble_l2cap_sm_sec_initiate(conn_handle, ltk, ediv, rand_val, auth);
+ rc = ble_l2cap_sm_enc_initiate(conn_handle, ltk, ediv, rand_val, auth);
return rc;
}
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/aeb46aba/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 81b5996..a8fe98f 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -1348,7 +1348,6 @@ ble_l2cap_sm_rx_key_exchange(uint16_t conn_handle, uint8_t op,
return rc;
}
-
/*****************************************************************************
* $rx *
*****************************************************************************/
@@ -1806,15 +1805,16 @@ ble_l2cap_sm_heartbeat(void)
}
}
+/**
+ * Initiates the pairing procedure for the specified connection.
+ */
int
-ble_l2cap_sm_initiate(uint16_t conn_handle)
+ble_l2cap_sm_pair_initiate(uint16_t conn_handle)
{
struct ble_l2cap_sm_proc *proc;
int rc;
- /* Make sure a pairing operation for this connection is not already in
- * progress.
- */
+ /* Make sure a procedure isn't already in progress for this connection. */
ble_hs_lock();
proc = ble_l2cap_sm_proc_find(conn_handle, BLE_L2CAP_SM_PROC_STATE_NONE,
-1, NULL);
@@ -1845,8 +1845,11 @@ done:
return rc;
}
+/**
+ * Initiates the encryption procedure for the specified connection.
+ */
int
-ble_l2cap_sm_sec_initiate(uint16_t conn_handle,
+ble_l2cap_sm_enc_initiate(uint16_t conn_handle,
uint8_t *ltk,
uint16_t ediv,
uint64_t rand_val,
@@ -1855,9 +1858,7 @@ ble_l2cap_sm_sec_initiate(uint16_t conn_handle,
struct ble_l2cap_sm_proc *proc;
int rc;
- /* Make sure a pairing operation for this connection is not already in
- * progress.
- */
+ /* Make sure a procedure isn't already in progress for this connection. */
ble_hs_lock();
proc = ble_l2cap_sm_proc_find(conn_handle, BLE_L2CAP_SM_PROC_STATE_NONE,
-1, NULL);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/aeb46aba/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 0ed311d..5838ba5 100644
--- a/net/nimble/host/src/ble_l2cap_sm_priv.h
+++ b/net/nimble/host/src/ble_l2cap_sm_priv.h
@@ -211,8 +211,8 @@ void ble_l2cap_sm_rx_encryption_change(struct hci_encrypt_change *evt);
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_initiate(uint16_t conn_handle);
-int ble_l2cap_sm_sec_initiate(uint16_t conn_handle, uint8_t *ltk,
+int ble_l2cap_sm_pair_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);
[3/4] incubator-mynewt-core git commit: BLE Host - rx slave security
request.
Posted by cc...@apache.org.
BLE Host - rx 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/91e81018
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/91e81018
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/91e81018
Branch: refs/heads/develop
Commit: 91e810186b882750a0f3fc48be7ad6b659e934e4
Parents: 28327e9
Author: Christopher Collins <cc...@apache.org>
Authored: Mon May 16 16:33:06 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Mon May 16 19:47:01 2016 -0700
----------------------------------------------------------------------
net/nimble/host/src/ble_l2cap_sm.c | 56 ++++++++++++++++-
net/nimble/host/src/ble_l2cap_sm_cmd.c | 46 ++++++++++++++
net/nimble/host/src/ble_l2cap_sm_priv.h | 17 +++++
net/nimble/host/src/test/ble_hs_test_util.c | 8 +++
net/nimble/host/src/test/ble_hs_test_util.h | 1 +
net/nimble/host/src/test/ble_l2cap_sm_test.c | 76 +++++++++++++++++++++++
6 files changed, 203 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/91e81018/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 9703519..05adfca 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -114,6 +114,7 @@ static ble_l2cap_sm_rx_fn ble_l2cap_sm_rx_pair_confirm;
static ble_l2cap_sm_rx_fn ble_l2cap_sm_rx_pair_random;
static ble_l2cap_sm_rx_fn ble_l2cap_sm_rx_pair_fail;
static ble_l2cap_sm_rx_fn ble_l2cap_sm_rx_key_exchange;
+static ble_l2cap_sm_rx_fn ble_l2cap_sm_rx_sec_req;
static ble_l2cap_sm_rx_fn * const ble_l2cap_sm_dispatch[] = {
[BLE_L2CAP_SM_OP_PAIR_REQ] = ble_l2cap_sm_rx_pair_req,
@@ -126,7 +127,7 @@ static ble_l2cap_sm_rx_fn * const ble_l2cap_sm_dispatch[] = {
[BLE_L2CAP_SM_OP_IDENTITY_INFO] = ble_l2cap_sm_rx_key_exchange,
[BLE_L2CAP_SM_OP_IDENTITY_ADDR_INFO] = ble_l2cap_sm_rx_key_exchange,
[BLE_L2CAP_SM_OP_SIGN_INFO] = ble_l2cap_sm_rx_key_exchange,
- [BLE_L2CAP_SM_OP_SEC_REQ] = ble_l2cap_sm_rx_noop,
+ [BLE_L2CAP_SM_OP_SEC_REQ] = ble_l2cap_sm_rx_sec_req,
[BLE_L2CAP_SM_OP_PAIR_PUBLIC_KEY] = ble_l2cap_sm_rx_noop,
[BLE_L2CAP_SM_OP_PAIR_DHKEY_CHECK] = ble_l2cap_sm_rx_noop,
[BLE_L2CAP_SM_OP_PAIR_KEYPRESS_NOTIFY] = ble_l2cap_sm_rx_noop,
@@ -1757,6 +1758,59 @@ ble_l2cap_sm_rx_encryption_change(struct hci_encrypt_change *evt)
}
static int
+ble_l2cap_sm_rx_sec_req(uint16_t conn_handle, uint8_t op, struct os_mbuf **om)
+{
+ struct ble_l2cap_sm_sec_req cmd;
+ struct ble_l2cap_sm_proc *proc;
+ struct ble_hs_conn *conn;
+ int rc;
+
+ rc = ble_hs_misc_pullup_base(om, BLE_L2CAP_SM_SEC_REQ_SZ);
+ if (rc != 0) {
+ return rc;
+ }
+
+ ble_l2cap_sm_sec_req_parse((*om)->om_data, (*om)->om_len, &cmd);
+
+ BLE_HS_LOG(DEBUG, "rxed sm sec req; authreq=%d\n", cmd.authreq);
+
+ ble_hs_lock();
+
+ /* Only handle the security request if 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;
+ } else {
+ conn = ble_hs_conn_find(conn_handle);
+ if (conn == NULL) {
+ rc = BLE_HS_ENOTCONN;
+ } else if (!(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) {
+ rc = BLE_HS_SM_US_ERR(BLE_L2CAP_SM_ERR_CMD_NOT_SUPP);
+ ble_l2cap_sm_pair_fail_tx(conn_handle,
+ BLE_L2CAP_SM_ERR_CMD_NOT_SUPP);
+ } else {
+ rc = 0;
+ }
+ }
+
+ ble_hs_unlock();
+
+ if (rc == 0) {
+ /* XXX: Ask app / someone if there is a persisted LTK such that:
+ * o It corresponds to this peer.
+ * o It meets the specified authreq criteria.
+ * For now, assume we don't have an appropriate LTK; initiate pairing.
+ */
+ rc = ble_l2cap_sm_pair_initiate(conn_handle);
+ }
+
+ return rc;
+}
+
+static int
ble_l2cap_sm_rx(uint16_t conn_handle, struct os_mbuf **om)
{
ble_l2cap_sm_rx_fn *rx_cb;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/91e81018/net/nimble/host/src/ble_l2cap_sm_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm_cmd.c b/net/nimble/host/src/ble_l2cap_sm_cmd.c
index 62149e6..14c5093 100644
--- a/net/nimble/host/src/ble_l2cap_sm_cmd.c
+++ b/net/nimble/host/src/ble_l2cap_sm_cmd.c
@@ -471,4 +471,50 @@ done:
return rc;
}
+void
+ble_l2cap_sm_sec_req_parse(void *payload, int len,
+ struct ble_l2cap_sm_sec_req *cmd)
+{
+ uint8_t *u8ptr;
+
+ BLE_HS_DBG_ASSERT(len >= BLE_L2CAP_SM_SEC_REQ_SZ);
+
+ u8ptr = payload;
+ cmd->authreq = *u8ptr;
+}
+
+void
+ble_l2cap_sm_sec_req_write(void *payload, int len,
+ struct ble_l2cap_sm_sec_req *cmd)
+{
+ uint8_t *u8ptr;
+
+ BLE_HS_DBG_ASSERT(len >= BLE_L2CAP_SM_HDR_SZ + BLE_L2CAP_SM_SEC_REQ_SZ);
+
+ u8ptr = payload;
+
+ u8ptr[0] = BLE_L2CAP_SM_OP_SEC_REQ;
+ u8ptr[1] = cmd->authreq;
+}
+
+int
+ble_l2cap_sm_sec_req_tx(uint16_t conn_handle, struct ble_l2cap_sm_sec_req *cmd)
+{
+ struct os_mbuf *txom;
+ int rc;
+
+ rc = ble_l2cap_sm_init_req(BLE_L2CAP_SM_SEC_REQ_SZ, &txom);
+ if (rc != 0) {
+ rc = BLE_HS_ENOMEM;
+ goto done;
+ }
+
+ ble_l2cap_sm_sec_req_write(txom->om_data, txom->om_len, cmd);
+ rc = ble_l2cap_sm_tx(conn_handle, txom);
+ txom = NULL;
+
+done:
+ os_mbuf_free_chain(txom);
+ return rc;
+}
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/91e81018/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 5838ba5..99070dc 100644
--- a/net/nimble/host/src/ble_l2cap_sm_priv.h
+++ b/net/nimble/host/src/ble_l2cap_sm_priv.h
@@ -141,6 +141,17 @@ struct ble_l2cap_sm_signing_info {
uint8_t sig_key_le[16];
};
+/**
+ * | Parameter | Size (octets) |
+ * +------------------------------------+-------------------+
+ * | (Code=0x0B) | 1 |
+ * | authreq | 1 |
+ */
+#define BLE_L2CAP_SM_SEC_REQ_SZ 1
+struct ble_l2cap_sm_sec_req {
+ uint8_t authreq;
+};
+
#if NIMBLE_OPT_SM
@@ -206,6 +217,12 @@ void ble_l2cap_sm_signing_info_parse(void *payload, int len,
struct ble_l2cap_sm_signing_info *cmd);
int ble_l2cap_sm_signing_info_tx(uint16_t conn_handle,
struct ble_l2cap_sm_signing_info *cmd);
+void ble_l2cap_sm_sec_req_parse(void *payload, int len,
+ struct ble_l2cap_sm_sec_req *cmd);
+void ble_l2cap_sm_sec_req_write(void *payload, int len,
+ struct ble_l2cap_sm_sec_req *cmd);
+int ble_l2cap_sm_sec_req_tx(uint16_t conn_handle,
+ struct ble_l2cap_sm_sec_req *cmd);
void ble_l2cap_sm_rx_encryption_change(struct hci_encrypt_change *evt);
int ble_l2cap_sm_rx_lt_key_req(struct hci_le_lt_key_req *evt);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/91e81018/net/nimble/host/src/test/ble_hs_test_util.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test_util.c b/net/nimble/host/src/test/ble_hs_test_util.c
index d0b8c0b..bfb4696 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.c
+++ b/net/nimble/host/src/test/ble_hs_test_util.c
@@ -117,6 +117,14 @@ ble_hs_test_util_prev_tx_queue_sz(void)
return cnt;
}
+void
+ble_hs_test_util_prev_tx_queue_clear(void)
+{
+ while (!STAILQ_EMPTY(&ble_hs_test_util_prev_tx_queue)) {
+ ble_hs_test_util_prev_tx_dequeue();
+ }
+}
+
void *
ble_hs_test_util_get_first_hci_tx(void)
{
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/91e81018/net/nimble/host/src/test/ble_hs_test_util.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test_util.h b/net/nimble/host/src/test/ble_hs_test_util.h
index baffffc..cd75452 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.h
+++ b/net/nimble/host/src/test/ble_hs_test_util.h
@@ -38,6 +38,7 @@ void ble_hs_test_util_prev_tx_enqueue(struct os_mbuf *om);
struct os_mbuf *ble_hs_test_util_prev_tx_dequeue(void);
struct os_mbuf *ble_hs_test_util_prev_tx_dequeue_pullup(void);
int ble_hs_test_util_prev_tx_queue_sz(void);
+void ble_hs_test_util_prev_tx_queue_clear(void);
void ble_hs_test_util_set_ack_params(uint16_t opcode, uint8_t status,
void *params, uint8_t params_len);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/91e81018/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 43d9350..5e3dce9 100644
--- a/net/nimble/host/src/test/ble_l2cap_sm_test.c
+++ b/net/nimble/host/src/test/ble_l2cap_sm_test.c
@@ -248,6 +248,36 @@ ble_l2cap_sm_test_util_rx_random(uint16_t conn_handle,
TEST_ASSERT_FATAL(rc == exp_status);
}
+static void
+ble_l2cap_sm_test_util_rx_sec_req(uint16_t conn_handle,
+ struct ble_l2cap_sm_sec_req *cmd,
+ int exp_status)
+{
+ struct hci_data_hdr hci_hdr;
+ struct os_mbuf *om;
+ void *v;
+ int payload_len;
+ int rc;
+
+ hci_hdr = BLE_L2CAP_SM_TEST_UTIL_HCI_HDR(
+ 2, BLE_HCI_PB_FIRST_FLUSH,
+ BLE_L2CAP_HDR_SZ + BLE_L2CAP_SM_HDR_SZ + BLE_L2CAP_SM_SEC_REQ_SZ);
+
+ om = ble_hs_misc_pkthdr();
+ TEST_ASSERT_FATAL(om != NULL);
+
+ payload_len = BLE_L2CAP_SM_HDR_SZ + BLE_L2CAP_SM_SEC_REQ_SZ;
+
+ v = os_mbuf_extend(om, payload_len);
+ TEST_ASSERT_FATAL(v != NULL);
+
+ ble_l2cap_sm_sec_req_write(v, payload_len, cmd);
+
+ rc = ble_hs_test_util_l2cap_rx_first_frag(conn_handle, BLE_L2CAP_CID_SM,
+ &hci_hdr, om);
+ TEST_ASSERT_FATAL(rc == exp_status);
+}
+
static struct os_mbuf *
ble_l2cap_sm_test_util_verify_tx_hdr(uint8_t sm_op, uint16_t payload_len)
{
@@ -1638,6 +1668,51 @@ TEST_CASE(ble_l2cap_sm_test_case_conn_broken)
TEST_ASSERT(!ble_l2cap_sm_test_sec_state.authenticated);
}
+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();
+
+ ble_hs_test_util_create_conn(2, ((uint8_t[6]){1,2,3,5,6,7}),
+ 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;
+
+ sec_req.authreq = 0;
+ ble_l2cap_sm_test_util_rx_sec_req(
+ 2, &sec_req, BLE_HS_SM_US_ERR(BLE_L2CAP_SM_ERR_CMD_NOT_SUPP));
+
+ ble_hs_test_util_tx_all();
+
+ fail.reason = BLE_L2CAP_SM_ERR_CMD_NOT_SUPP;
+ ble_l2cap_sm_test_util_verify_tx_pair_fail(&fail);
+
+ /*** Pairing already in progress; ignore security request. */
+ rc = ble_l2cap_sm_pair_initiate(2);
+ TEST_ASSERT_FATAL(rc == 0);
+ ble_hs_test_util_tx_all();
+ ble_hs_test_util_prev_tx_queue_clear();
+
+ ble_l2cap_sm_test_util_rx_sec_req(2, &sec_req, BLE_HS_EALREADY);
+ ble_hs_test_util_tx_all();
+ TEST_ASSERT(ble_hs_test_util_prev_tx_queue_sz() == 0);
+}
+
TEST_SUITE(ble_l2cap_sm_test_suite)
{
ble_l2cap_sm_test_case_peer_fail_inval();
@@ -1649,6 +1724,7 @@ TEST_SUITE(ble_l2cap_sm_test_suite)
ble_l2cap_sm_test_case_peer_bonding_good();
ble_l2cap_sm_test_case_peer_bonding_bad();
ble_l2cap_sm_test_case_conn_broken();
+ ble_l2cap_sm_test_case_peer_sec_req_inval();
}
#endif
[4/4] incubator-mynewt-core git commit: BLE Host - tx slave security
request.
Posted by cc...@apache.org.
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/develop
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