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/03/29 02:36:31 UTC
incubator-mynewt-core git commit: Some preliminary passkey & OOB.
Repository: incubator-mynewt-core
Updated Branches:
refs/heads/develop 44cc9fd67 -> 696683c9a
Some preliminary passkey & OOB.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/696683c9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/696683c9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/696683c9
Branch: refs/heads/develop
Commit: 696683c9af2ded7d741f9d2e26d9716420f58ee9
Parents: 44cc9fd
Author: Christopher Collins <cc...@apache.org>
Authored: Mon Mar 28 14:15:45 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Mon Mar 28 17:36:05 2016 -0700
----------------------------------------------------------------------
net/nimble/host/include/host/ble_gap.h | 2 +-
net/nimble/host/include/host/ble_hs.h | 75 +++++++------
net/nimble/host/include/host/ble_l2cap.h | 28 ++++-
net/nimble/host/pkg.yml | 4 +-
net/nimble/host/src/ble_gap.c | 30 +----
net/nimble/host/src/ble_gap_priv.h | 5 +-
net/nimble/host/src/ble_hs_cfg.c | 8 ++
net/nimble/host/src/ble_l2cap_sig.c | 4 +-
net/nimble/host/src/ble_l2cap_sm.c | 127 ++++++++++++++++------
net/nimble/host/src/ble_l2cap_sm.h | 15 ---
net/nimble/host/src/test/ble_l2cap_sm_test.c | 62 +++++++++--
11 files changed, 234 insertions(+), 126 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/include/host/ble_gap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_gap.h b/net/nimble/host/include/host/ble_gap.h
index 872b3ec..c9ad502 100644
--- a/net/nimble/host/include/host/ble_gap.h
+++ b/net/nimble/host/include/host/ble_gap.h
@@ -130,7 +130,7 @@ struct ble_gap_upd_params {
};
struct ble_gap_sec_params {
- uint8_t enc_type;
+ uint8_t pair_alg;
unsigned enc_enabled:1;
unsigned auth_enabled:1;
};
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/include/host/ble_hs.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_hs.h b/net/nimble/host/include/host/ble_hs.h
index c532ca0..56c67bb 100644
--- a/net/nimble/host/include/host/ble_hs.h
+++ b/net/nimble/host/include/host/ble_hs.h
@@ -29,38 +29,41 @@
#include "host/ble_uuid.h"
#include "host/host_hci.h"
-#define BLE_HS_CONN_HANDLE_NONE 0xffff
-
-#define BLE_HS_EAGAIN 1
-#define BLE_HS_EALREADY 2
-#define BLE_HS_EINVAL 3
-#define BLE_HS_EMSGSIZE 4
-#define BLE_HS_ENOENT 5
-#define BLE_HS_ENOMEM 6
-#define BLE_HS_ENOTCONN 7
-#define BLE_HS_ENOTSUP 8
-#define BLE_HS_EAPP 9
-#define BLE_HS_EBADDATA 10
-#define BLE_HS_EOS 11
-#define BLE_HS_ECONGESTED 12
-#define BLE_HS_ECONTROLLER 13
-#define BLE_HS_ETIMEOUT 14
-#define BLE_HS_EDONE 15
-#define BLE_HS_EBUSY 16
-#define BLE_HS_EREJECT 17
-#define BLE_HS_EUNKNOWN 18
-
-#define BLE_HS_ERR_ATT_BASE 0x100 /* 256 */
-#define BLE_HS_ATT_ERR(x) ((x) ? BLE_HS_ERR_ATT_BASE + (x) : 0)
-
-#define BLE_HS_ERR_HCI_BASE 0x200 /* 512 */
-#define BLE_HS_HCI_ERR(x) ((x) ? BLE_HS_ERR_HCI_BASE + (x) : 0)
-
-#define BLE_HS_ERR_L2C_BASE 0x300 /* 768 */
-#define BLE_HS_L2C_ERR(x) ((x) ? BLE_HS_ERR_L2C_BASE + (x) : 0)
-
-#define BLE_HS_ERR_SM_BASE 0x400 /* 1024 */
-#define BLE_HS_SM_ERR(x) ((x) ? BLE_HS_ERR_SM_BASE + (x) : 0)
+#define BLE_HS_CONN_HANDLE_NONE 0xffff
+
+#define BLE_HS_EAGAIN 1
+#define BLE_HS_EALREADY 2
+#define BLE_HS_EINVAL 3
+#define BLE_HS_EMSGSIZE 4
+#define BLE_HS_ENOENT 5
+#define BLE_HS_ENOMEM 6
+#define BLE_HS_ENOTCONN 7
+#define BLE_HS_ENOTSUP 8
+#define BLE_HS_EAPP 9
+#define BLE_HS_EBADDATA 10
+#define BLE_HS_EOS 11
+#define BLE_HS_ECONGESTED 12
+#define BLE_HS_ECONTROLLER 13
+#define BLE_HS_ETIMEOUT 14
+#define BLE_HS_EDONE 15
+#define BLE_HS_EBUSY 16
+#define BLE_HS_EREJECT 17
+#define BLE_HS_EUNKNOWN 18
+
+#define BLE_HS_ERR_ATT_BASE 0x100 /* 256 */
+#define BLE_HS_ATT_ERR(x) ((x) ? BLE_HS_ERR_ATT_BASE + (x) : 0)
+
+#define BLE_HS_ERR_HCI_BASE 0x200 /* 512 */
+#define BLE_HS_HCI_ERR(x) ((x) ? BLE_HS_ERR_HCI_BASE + (x) : 0)
+
+#define BLE_HS_ERR_L2C_BASE 0x300 /* 768 */
+#define BLE_HS_L2C_ERR(x) ((x) ? BLE_HS_ERR_L2C_BASE + (x) : 0)
+
+#define BLE_HS_ERR_SM_US_BASE 0x400 /* 1024 */
+#define BLE_HS_SM_US_ERR(x) ((x) ? BLE_HS_ERR_SM_US_BASE + (x) : 0)
+
+#define BLE_HS_ERR_SM_THEM_BASE 0x400 /* 1024 */
+#define BLE_HS_SM_THEM_ERR(x) ((x) ? BLE_HS_ERR_SM_THEM_BASE + (x) : 0)
struct ble_hs_cfg {
/** HCI settings. */
@@ -87,6 +90,14 @@ struct ble_hs_cfg {
uint8_t max_l2cap_chans;
uint8_t max_l2cap_sig_procs;
uint8_t max_l2cap_sm_procs;
+
+ /** Security manager settings. */
+ uint8_t sm_io_cap;
+ unsigned sm_oob_data_flag:1;
+ unsigned sm_bonding:1;
+ unsigned sm_mitm:1;
+ unsigned sm_sc:1;
+ unsigned sm_keypress:1;
};
extern const struct ble_hs_cfg ble_hs_cfg_dflt;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/include/host/ble_l2cap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_l2cap.h b/net/nimble/host/include/host/ble_l2cap.h
index 444f5c1..76c838b 100644
--- a/net/nimble/host/include/host/ble_l2cap.h
+++ b/net/nimble/host/include/host/ble_l2cap.h
@@ -47,9 +47,9 @@ struct ble_hs_conn;
#define BLE_L2CAP_SIG_OP_FLOW_CTRL_CREDIT 0x16
#define BLE_L2CAP_SIG_OP_MAX 0x17
-#define BLE_L2CAP_ERR_CMD_NOT_UNDERSTOOD 0x0000
-#define BLE_L2CAP_ERR_MTU_EXCEEDED 0x0001
-#define BLE_L2CAP_ERR_INVALID_CID 0x0002
+#define BLE_L2CAP_SIG_ERR_CMD_NOT_UNDERSTOOD 0x0000
+#define BLE_L2CAP_SIG_ERR_MTU_EXCEEDED 0x0001
+#define BLE_L2CAP_SIG_ERR_INVALID_CID 0x0002
#define BLE_L2CAP_SM_OP_PAIR_REQ 0x01
#define BLE_L2CAP_SM_OP_PAIR_RSP 0x02
@@ -66,6 +66,25 @@ struct ble_hs_conn;
#define BLE_L2CAP_SM_OP_PAIR_DHKEY_CHECK 0x0d
#define BLE_L2CAP_SM_OP_PAIR_KEYPRESS_NOTIFY 0x0e
+#define BLE_L2CAP_SM_ERR_PASSKEY 0x01
+#define BLE_L2CAP_SM_ERR_OOB 0x02
+#define BLE_L2CAP_SM_ERR_AUTHREQ 0x03
+#define BLE_L2CAP_SM_ERR_CONFIRM_MISMATCH 0x04
+#define BLE_L2CAP_SM_ERR_PAIR_NOT_SUPP 0x05
+#define BLE_L2CAP_SM_ERR_ENC_KEY_SZ 0x06
+#define BLE_L2CAP_SM_ERR_CMD_NOT_SUPP 0x07
+#define BLE_L2CAP_SM_ERR_UNSPECIFIED 0x08
+#define BLE_L2CAP_SM_ERR_REPEATED 0x09
+#define BLE_L2CAP_SM_ERR_INVAL 0x0a
+#define BLE_L2CAP_SM_ERR_DHKEY 0x0b
+#define BLE_L2CAP_SM_ERR_NUM_CMP 0x0c
+#define BLE_L2CAP_SM_ERR_ALREADY 0x0d
+#define BLE_L2CAP_SM_ERR_CROSS_TRANS 0x0e
+
+#define BLE_L2CAP_SM_PAIR_ALG_JW 0
+#define BLE_L2CAP_SM_PAIR_ALG_PASSKEY 1
+#define BLE_L2CAP_SM_PAIR_ALG_OOB 2
+
typedef void ble_l2cap_sig_update_fn(int status, void *arg);
struct ble_l2cap_sig_update_params {
@@ -79,4 +98,7 @@ int ble_l2cap_sig_update(uint16_t conn_handle,
struct ble_l2cap_sig_update_params *params,
ble_l2cap_sig_update_fn *cb, void *cb_arg);
+
+int ble_l2cap_sm_set_tk(uint16_t conn_handle, uint8_t *tk);
+
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/pkg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/host/pkg.yml b/net/nimble/host/pkg.yml
index 679c054..ef4cf2c 100644
--- a/net/nimble/host/pkg.yml
+++ b/net/nimble/host/pkg.yml
@@ -38,5 +38,7 @@ pkg.req_apis:
# Satisfy capability dependencies for the self-contained test executable.
pkg.deps.SELFTEST: libs/console/stub
-pkg.cflags.SELFTEST: -DPHONY_TRANSPORT
+pkg.cflags.SELFTEST:
+ - -DPHONY_TRANSPORT=1
+ - -DNIMBLE_OPT_SM=1
pkg.cflags.TEST: -DBLE_HS_DEBUG
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/src/ble_gap.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap.c b/net/nimble/host/src/ble_gap.c
index 324f8da..eab7d50 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -3068,20 +3068,13 @@ done:
*****************************************************************************/
void
-ble_gap_encryption_changed(uint16_t conn_handle,
- struct ble_gap_sec_params *sec_params)
+ble_gap_security_event(uint16_t conn_handle, int status,
+ struct ble_gap_sec_params *sec_params)
{
struct ble_gap_conn_ctxt ctxt;
struct ble_gap_snapshot snap;
struct ble_hs_conn *conn;
- if (!sec_params->enc_enabled) {
- /* XXX: Encryption got disabled. Does this ever happen? If so, the
- * application needs to be notified of the change.
- */
- return;
- }
-
ble_hs_conn_lock();
conn = ble_hs_conn_find(conn_handle);
@@ -3100,25 +3093,6 @@ ble_gap_encryption_changed(uint16_t conn_handle,
memset(&ctxt, 0, sizeof ctxt);
ctxt.desc = &snap.desc;
ctxt.sec_params = sec_params;
- ble_gap_call_conn_cb(BLE_GAP_EVENT_SECURITY, 0, &ctxt,
- snap.cb, snap.cb_arg);
-}
-
-void
-ble_gap_security_fail(uint16_t conn_handle, int status)
-{
- struct ble_gap_conn_ctxt ctxt;
- struct ble_gap_snapshot snap;
- int rc;
-
- rc = ble_gap_find_snapshot(conn_handle, &snap);
- if (rc != 0) {
- /* No longer connected. */
- return;
- }
-
- memset(&ctxt, 0, sizeof ctxt);
- ctxt.desc = &snap.desc;
ble_gap_call_conn_cb(BLE_GAP_EVENT_SECURITY, status, &ctxt,
snap.cb, snap.cb_arg);
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/src/ble_gap_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap_priv.h b/net/nimble/host/src/ble_gap_priv.h
index 7facca9..d290480 100644
--- a/net/nimble/host/src/ble_gap_priv.h
+++ b/net/nimble/host/src/ble_gap_priv.h
@@ -74,9 +74,8 @@ void ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt);
void ble_gap_rx_param_req(struct hci_le_conn_param_req *evt);
int ble_gap_rx_l2cap_update_req(uint16_t conn_handle,
struct ble_gap_upd_params *params);
-void ble_gap_encryption_changed(uint16_t conn_handle,
- struct ble_gap_sec_params *sec_params);
-void ble_gap_security_fail(uint16_t conn_handle, int status);
+void ble_gap_security_event(uint16_t conn_handle, int status,
+ struct ble_gap_sec_params *sec_params);
int ble_gap_master_in_progress(void);
int ble_gap_slave_in_progress(void);
int ble_gap_update_in_progress(uint16_t conn_handle);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/src/ble_hs_cfg.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_cfg.c b/net/nimble/host/src/ble_hs_cfg.c
index 9e79bbe..860ef3c 100644
--- a/net/nimble/host/src/ble_hs_cfg.c
+++ b/net/nimble/host/src/ble_hs_cfg.c
@@ -50,6 +50,14 @@ const struct ble_hs_cfg ble_hs_cfg_dflt = {
.max_l2cap_chans = 16,
.max_l2cap_sig_procs = 8,
.max_l2cap_sm_procs = 1,
+
+ /** Security manager settings. */
+ .sm_io_cap = 3,
+ .sm_oob_data_flag = 0,
+ .sm_bonding = 0,
+ .sm_mitm = 0,
+ .sm_sc = 0,
+ .sm_keypress = 0,
};
struct ble_hs_cfg ble_hs_cfg;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/src/ble_l2cap_sig.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig.c b/net/nimble/host/src/ble_l2cap_sig.c
index 112d541..f0e3098 100644
--- a/net/nimble/host/src/ble_l2cap_sig.c
+++ b/net/nimble/host/src/ble_l2cap_sig.c
@@ -430,7 +430,7 @@ ble_l2cap_sig_update_req_rx(uint16_t conn_handle,
/* Only a master can process an update request. */
if (!is_master) {
ble_l2cap_sig_reject_tx(conn_handle, hdr->identifier,
- BLE_L2CAP_ERR_CMD_NOT_UNDERSTOOD);
+ BLE_L2CAP_SIG_ERR_CMD_NOT_UNDERSTOOD);
return BLE_HS_ENOTSUP;
}
@@ -620,7 +620,7 @@ ble_l2cap_sig_rx(uint16_t conn_handle, struct os_mbuf **om)
rx_cb = ble_l2cap_sig_dispatch_get(hdr.op);
if (rx_cb == NULL) {
ble_l2cap_sig_reject_tx(conn_handle, hdr.identifier,
- BLE_L2CAP_ERR_CMD_NOT_UNDERSTOOD);
+ BLE_L2CAP_SIG_ERR_CMD_NOT_UNDERSTOOD);
rc = BLE_HS_ENOTSUP;
} else {
rc = rx_cb(conn_handle, &hdr, om);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/src/ble_l2cap_sm.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm.c b/net/nimble/host/src/ble_l2cap_sm.c
index be2f6f1..6e13952 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -40,14 +40,12 @@
#define BLE_L2CAP_SM_PROC_F_INITIATOR 0x01
-#define BLE_L2CAP_SM_KEYGEN_METHOD_JW 0
-
typedef uint16_t ble_l2cap_sm_proc_flags;
struct ble_l2cap_sm_proc {
struct ble_fsm_proc fsm_proc;
ble_l2cap_sm_proc_flags flags;
- uint8_t keygen_method;
+ uint8_t pair_alg;
/* XXX: Minimum security requirements. */
@@ -55,6 +53,7 @@ struct ble_l2cap_sm_proc {
struct {
struct ble_l2cap_sm_pair_cmd pair_req;
struct ble_l2cap_sm_pair_cmd pair_rsp;
+ uint8_t tk[16];
uint8_t confirm_their[16];
uint8_t rand_our[16];
uint8_t rand_their[16];
@@ -349,13 +348,44 @@ ble_l2cap_sm_rx_noop(uint16_t conn_handle, uint8_t op, struct os_mbuf **om)
return 0;
}
+static int
+ble_l2cap_sm_request_tk(struct ble_l2cap_sm_proc *proc)
+{
+ if (proc->pair_alg == BLE_L2CAP_SM_PAIR_ALG_JW) {
+ ble_l2cap_sm_proc_set_pending(proc);
+ } else {
+ /* XXX: Ask application for TK. */
+ }
+ return 0;
+}
+
+static void
+ble_l2cap_sm_sec_params(struct ble_l2cap_sm_proc *proc,
+ struct ble_gap_sec_params *out_sec_params,
+ int enc_enabled)
+{
+ out_sec_params->pair_alg = proc->pair_alg;
+ out_sec_params->enc_enabled = enc_enabled;
+ out_sec_params->auth_enabled = 0; // XXX
+}
+
+static void
+ble_l2cap_sm_gap_event(struct ble_l2cap_sm_proc *proc, int status,
+ int enc_enabled)
+{
+ struct ble_gap_sec_params sec_params;
+
+ ble_l2cap_sm_sec_params(proc, &sec_params, enc_enabled);
+ ble_gap_security_event(proc->fsm_proc.conn_handle, status, &sec_params);
+}
+
/*****************************************************************************
* $pair *
*****************************************************************************/
static int
ble_l2cap_sm_pair_req_handle(struct ble_l2cap_sm_proc *proc,
- struct ble_l2cap_sm_pair_cmd *req)
+ struct ble_l2cap_sm_pair_cmd *req)
{
proc->phase_1_2.pair_req = *req;
ble_l2cap_sm_proc_set_pending(proc);
@@ -367,27 +397,37 @@ static int
ble_l2cap_sm_pair_rsp_handle(struct ble_l2cap_sm_proc *proc,
struct ble_l2cap_sm_pair_cmd *rsp)
{
+ int rc;
+
proc->phase_1_2.pair_rsp = *rsp;
+
proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_CONFIRM;
- ble_l2cap_sm_proc_set_pending(proc);
+ proc->fsm_proc.flags &= ~BLE_FSM_PROC_F_EXPECTING;
/* XXX: Assume legacy "Just Works" for now. */
- proc->keygen_method = BLE_L2CAP_SM_KEYGEN_METHOD_JW;
+ proc->pair_alg = BLE_L2CAP_SM_PAIR_ALG_JW;
+
+ rc = ble_l2cap_sm_request_tk(proc);
+ if (rc != 0) {
+ ble_l2cap_sm_set_fail_state(proc, rc);
+ return rc;
+ }
return 0;
}
-
static int
ble_l2cap_sm_pair_kick(struct ble_l2cap_sm_proc *proc)
{
struct ble_l2cap_sm_pair_cmd cmd;
int rc;
- /* XXX: Assume legacy "Just Works" for now. */
- cmd.io_cap = 3;
- cmd.oob_data_flag = 0;
- cmd.authreq = 0;
+ cmd.io_cap = ble_hs_cfg.sm_io_cap;
+ cmd.oob_data_flag = ble_hs_cfg.sm_oob_data_flag;
+ cmd.authreq = (ble_hs_cfg.sm_bonding << 0) |
+ (ble_hs_cfg.sm_mitm << 2) |
+ (ble_hs_cfg.sm_sc << 3) |
+ (ble_hs_cfg.sm_keypress << 4);
cmd.max_enc_key_size = 16;
cmd.init_key_dist = 0;
cmd.resp_key_dist = 0;
@@ -401,7 +441,7 @@ ble_l2cap_sm_pair_kick(struct ble_l2cap_sm_proc *proc)
if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
proc->phase_1_2.pair_req = cmd;
} else {
- proc->keygen_method = BLE_L2CAP_SM_KEYGEN_METHOD_JW;
+ proc->pair_alg = BLE_L2CAP_SM_PAIR_ALG_JW;
proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_CONFIRM;
proc->phase_1_2.pair_rsp = cmd;
}
@@ -419,8 +459,6 @@ ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc,
uint8_t *iat, uint8_t *rat,
uint8_t *ia, uint8_t *ra)
{
- static uint8_t zeros[16];
-
struct ble_hs_conn *conn;
int rc;
@@ -447,7 +485,7 @@ ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc,
return BLE_HS_ENOTCONN;
}
- memcpy(k, zeros, 16); /* XXX: Assume legacy "Just Works." */
+ memcpy(k, proc->phase_1_2.tk, sizeof proc->phase_1_2.tk);
rc = ble_l2cap_sm_pair_cmd_write(
preq, BLE_L2CAP_SM_HDR_SZ + BLE_L2CAP_SM_PAIR_CMD_SZ, 1,
@@ -514,12 +552,20 @@ static int
ble_l2cap_sm_confirm_handle(struct ble_l2cap_sm_proc *proc,
struct ble_l2cap_sm_pair_confirm *cmd)
{
+ int rc;
+
memcpy(proc->phase_1_2.confirm_their, cmd->value, 16);
if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_RANDOM;
+ ble_l2cap_sm_proc_set_pending(proc);
+ } else {
+ rc = ble_l2cap_sm_request_tk(proc);
+ if (rc != 0) {
+ ble_l2cap_sm_set_fail_state(proc, rc);
+ return rc;
+ }
}
- ble_l2cap_sm_proc_set_pending(proc);
return 0;
}
@@ -605,6 +651,9 @@ ble_l2cap_sm_fail_kick(struct ble_l2cap_sm_proc *proc)
cmd.reason = proc->fail.reason;
ble_l2cap_sm_pair_fail_tx(proc->fsm_proc.conn_handle, &cmd);
+ /* Notify application of failure. */
+ ble_l2cap_sm_gap_event(proc, BLE_HS_SM_US_ERR(cmd.reason), 0);
+
return BLE_HS_EDONE;
}
@@ -612,8 +661,7 @@ static int
ble_l2cap_sm_fail_handle(struct ble_l2cap_sm_proc *proc,
struct ble_l2cap_sm_pair_fail *cmd)
{
- ble_gap_security_fail(proc->fsm_proc.conn_handle,
- BLE_HS_SM_ERR(cmd->reason));
+ ble_l2cap_sm_gap_event(proc, BLE_HS_SM_THEM_ERR(cmd->reason), 0);
/* Procedure should now be terminated (return nonzero). */
return 1;
@@ -628,7 +676,7 @@ ble_l2cap_sm_lt_key_req_reply_ack_handle(struct ble_l2cap_sm_proc *proc,
struct ble_hci_ack *ack)
{
if (ack->bha_status != 0) {
- ble_gap_security_fail(proc->fsm_proc.conn_handle, ack->bha_status);
+ ble_l2cap_sm_gap_event(proc, ack->bha_status, 0);
} else {
proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_ENC_CHANGE;
}
@@ -664,7 +712,7 @@ ble_l2cap_sm_lt_key_req_kick(struct ble_l2cap_sm_proc *proc)
rc = ble_hci_sched_enqueue(ble_l2cap_sm_lt_key_req_reply_tx, proc,
&proc->hci.handle);
if (rc != 0) {
- ble_gap_security_fail(proc->fsm_proc.conn_handle, rc);
+ ble_l2cap_sm_gap_event(proc, rc, 0);
return BLE_HS_EDONE;
}
@@ -678,15 +726,13 @@ ble_l2cap_sm_lt_key_req_handle(struct ble_l2cap_sm_proc *proc,
struct hci_le_lt_key_req *evt)
{
uint8_t key[16];
- /* XXX: Assume legacy "Just Works". */
- uint8_t k[16] = {0};
int rc;
/* Generate the key. */
- rc = ble_l2cap_sm_alg_s1(k, proc->phase_1_2.rand_our,
+ rc = ble_l2cap_sm_alg_s1(proc->phase_1_2.tk, proc->phase_1_2.rand_our,
proc->phase_1_2.rand_their, key);
if (rc != 0) {
- ble_gap_security_fail(proc->fsm_proc.conn_handle, rc);
+ ble_l2cap_sm_gap_event(proc, rc, 0);
return rc;
}
@@ -945,7 +991,6 @@ ble_l2cap_sm_rx_lt_key_req_reply_ack(struct ble_hci_ack *ack, void *arg)
void
ble_l2cap_sm_rx_encryption_change(struct hci_encrypt_change *evt)
{
- struct ble_gap_sec_params sec_params;
struct ble_l2cap_sm_proc *proc;
proc = ble_l2cap_sm_proc_extract(
@@ -960,13 +1005,10 @@ ble_l2cap_sm_rx_encryption_change(struct hci_encrypt_change *evt)
}
if (evt->status != 0) {
- ble_gap_security_fail(evt->connection_handle,
- BLE_HS_SM_ERR(evt->status));
+ ble_l2cap_sm_gap_event(proc, BLE_HS_HCI_ERR(evt->status), 0);
} else {
- sec_params.enc_type = proc->keygen_method; // XXX
- sec_params.enc_enabled = evt->encryption_enabled & 0x01; /* LE bit. */
- sec_params.auth_enabled = 0; // XXX
- ble_gap_encryption_changed(evt->connection_handle, &sec_params);
+ ble_l2cap_sm_gap_event(proc, 0,
+ evt->encryption_enabled & 0x01 /* LE bit. */);
}
/* The pairing procedure is now complete. */
@@ -1034,6 +1076,29 @@ ble_l2cap_sm_create_chan(void)
return chan;
}
+int
+ble_l2cap_sm_set_tk(uint16_t conn_handle, uint8_t *tk)
+{
+ struct ble_l2cap_sm_proc *proc;
+
+ proc = ble_l2cap_sm_proc_extract(
+ &(struct ble_l2cap_sm_extract_arg) {
+ .conn_handle = conn_handle,
+ .op = BLE_L2CAP_SM_PROC_OP_CONFIRM,
+ .initiator = -1,
+ }
+ );
+ if (proc == NULL) {
+ return BLE_HS_ENOENT;
+ }
+
+ memcpy(proc->phase_1_2.tk, tk, 16);
+
+ ble_l2cap_sm_proc_set_pending(proc);
+
+ return 0;
+}
+
/**
* Lock restrictions:
* o Caller unlocks ble_hs_conn.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/src/ble_l2cap_sm.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm.h b/net/nimble/host/src/ble_l2cap_sm.h
index 5051bd6..e7d69cc 100644
--- a/net/nimble/host/src/ble_l2cap_sm.h
+++ b/net/nimble/host/src/ble_l2cap_sm.h
@@ -23,21 +23,6 @@
struct ble_gap_sec_params;
struct hci_le_lt_key_req;
-#define BLE_L2CAP_SM_ERR_PASSKEY 0x01
-#define BLE_L2CAP_SM_ERR_OOB 0x02
-#define BLE_L2CAP_SM_ERR_AUTHREQ 0x03
-#define BLE_L2CAP_SM_ERR_CONFIRM_MISMATCH 0x04
-#define BLE_L2CAP_SM_ERR_PAIR_NOT_SUPP 0x05
-#define BLE_L2CAP_SM_ERR_ENC_KEY_SZ 0x06
-#define BLE_L2CAP_SM_ERR_CMD_NOT_SUPP 0x07
-#define BLE_L2CAP_SM_ERR_UNSPECIFIED 0x08
-#define BLE_L2CAP_SM_ERR_REPEATED 0x09
-#define BLE_L2CAP_SM_ERR_INVAL 0x0a
-#define BLE_L2CAP_SM_ERR_DHKEY 0x0b
-#define BLE_L2CAP_SM_ERR_NUM_CMP 0x0c
-#define BLE_L2CAP_SM_ERR_ALREADY 0x0d
-#define BLE_L2CAP_SM_ERR_CROSS_TRANS 0x0e
-
#define BLE_L2CAP_SM_MTU 65
#define BLE_L2CAP_SM_HDR_SZ 1
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696683c9/net/nimble/host/src/test/ble_l2cap_sm_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_l2cap_sm_test.c b/net/nimble/host/src/test/ble_l2cap_sm_test.c
index 2ed093a..33fe1b1 100644
--- a/net/nimble/host/src/test/ble_l2cap_sm_test.c
+++ b/net/nimble/host/src/test/ble_l2cap_sm_test.c
@@ -29,6 +29,10 @@
#if NIMBLE_OPT_SM
+int ble_l2cap_sm_test_gap_event;
+int ble_l2cap_sm_test_gap_status;
+struct ble_gap_sec_params ble_l2cap_sm_test_sec_params;
+
/*****************************************************************************
* $util *
*****************************************************************************/
@@ -44,20 +48,23 @@ static void
ble_l2cap_sm_test_util_init(void)
{
ble_hs_test_util_init();
- //ble_l2cap_test_update_status = -1;
- //ble_l2cap_test_update_arg = (void *)(uintptr_t)-1;
+
+ ble_l2cap_sm_test_gap_event = -1;
+ ble_l2cap_sm_test_gap_status = -1;
+ memset(&ble_l2cap_sm_test_sec_params, 0xff,
+ sizeof ble_l2cap_sm_test_sec_params);
}
static int
ble_l2cap_sm_test_util_conn_cb(int event, int status,
struct ble_gap_conn_ctxt *ctxt, void *arg)
{
- int *accept;
-
switch (event) {
- case BLE_GAP_EVENT_L2CAP_UPDATE_REQ:
- accept = arg;
- return !*accept;
+ case BLE_GAP_EVENT_SECURITY:
+ ble_l2cap_sm_test_gap_event = event;
+ ble_l2cap_sm_test_gap_status = status;
+ ble_l2cap_sm_test_sec_params = *ctxt->sec_params;
+ return 0;
default:
return 0;
@@ -321,6 +328,8 @@ ble_l2cap_sm_test_util_peer_lgcy_good(
struct ble_l2cap_sm_pair_confirm *confirm_rsp,
struct ble_l2cap_sm_pair_random *random_req,
struct ble_l2cap_sm_pair_random *random_rsp,
+ int pair_alg,
+ uint8_t *tk,
uint8_t *stk,
uint64_t r,
uint16_t ediv)
@@ -392,8 +401,22 @@ ble_l2cap_sm_test_util_peer_lgcy_good(
ble_l2cap_sm_test_util_rx_enc_change(2, 0, 1);
/* Pairing should now be complete. */
- TEST_ASSERT(conn->bhc_sec_params.enc_enabled);
TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
+
+ /* Verify that security callback was executed. */
+ TEST_ASSERT(ble_l2cap_sm_test_gap_event == BLE_GAP_EVENT_SECURITY);
+ TEST_ASSERT(ble_l2cap_sm_test_gap_status == 0);
+ TEST_ASSERT(ble_l2cap_sm_test_sec_params.pair_alg == pair_alg);
+ TEST_ASSERT(ble_l2cap_sm_test_sec_params.enc_enabled);
+ TEST_ASSERT(!ble_l2cap_sm_test_sec_params.auth_enabled);
+
+ /* Verify that connection has correct security state. */
+ TEST_ASSERT(ble_l2cap_sm_test_sec_params.pair_alg ==
+ conn->bhc_sec_params.pair_alg);
+ TEST_ASSERT(ble_l2cap_sm_test_sec_params.enc_enabled ==
+ conn->bhc_sec_params.enc_enabled);
+ TEST_ASSERT(ble_l2cap_sm_test_sec_params.auth_enabled ==
+ conn->bhc_sec_params.auth_enabled);
}
static void
@@ -449,9 +472,26 @@ ble_l2cap_sm_test_util_peer_lgcy_fail(
/* The proc should now be freed. */
TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
+
+ /* Verify that security callback was executed. */
+ TEST_ASSERT(ble_l2cap_sm_test_gap_event == BLE_GAP_EVENT_SECURITY);
+ TEST_ASSERT(ble_l2cap_sm_test_gap_status ==
+ BLE_HS_SM_US_ERR(BLE_L2CAP_SM_ERR_CONFIRM_MISMATCH));
+ TEST_ASSERT(ble_l2cap_sm_test_sec_params.pair_alg ==
+ BLE_L2CAP_SM_PAIR_ALG_JW);
+ TEST_ASSERT(!ble_l2cap_sm_test_sec_params.enc_enabled);
+ TEST_ASSERT(!ble_l2cap_sm_test_sec_params.auth_enabled);
+
+ /* Verify that connection has correct security state. */
+ TEST_ASSERT(ble_l2cap_sm_test_sec_params.pair_alg ==
+ conn->bhc_sec_params.pair_alg);
+ TEST_ASSERT(ble_l2cap_sm_test_sec_params.enc_enabled ==
+ conn->bhc_sec_params.enc_enabled);
+ TEST_ASSERT(ble_l2cap_sm_test_sec_params.auth_enabled ==
+ conn->bhc_sec_params.auth_enabled);
}
-TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_good)
+TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_jw_good)
{
ble_l2cap_sm_test_util_peer_lgcy_good(
((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
@@ -496,6 +536,8 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_good)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
} }),
+ BLE_L2CAP_SM_PAIR_ALG_JW,
+ NULL,
((uint8_t[16]) {
0xe6, 0xb3, 0x05, 0xd4, 0xc3, 0x67, 0xf0, 0x45,
0x38, 0x8f, 0xe7, 0x33, 0x0d, 0x51, 0x8e, 0xa4,
@@ -558,7 +600,7 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_fail)
TEST_SUITE(ble_l2cap_sm_test_suite)
{
- ble_l2cap_sm_test_case_peer_lgcy_good();
+ ble_l2cap_sm_test_case_peer_lgcy_jw_good();
ble_l2cap_sm_test_case_peer_lgcy_fail();
}
#endif