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/04/09 03:22:00 UTC
incubator-mynewt-core git commit: ble host - fix LTK generation bugs
Repository: incubator-mynewt-core
Updated Branches:
refs/heads/develop 03679c9ea -> c8d9ce1c2
ble host - fix LTK generation bugs
There were three bugs:
* The LTK was getting byte-swapped twice before being passed to the
controller. (should be little endian; was big endian).
* The initiator was never actually generating a key; it was sending
garbage to the controller!
* The slave was generating the key too late in the process. As a
consequence, some inputs into the s1 function had been rendered invalid
by overlaid data (they are in a union).
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/c8d9ce1c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/c8d9ce1c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/c8d9ce1c
Branch: refs/heads/develop
Commit: c8d9ce1c288bb80a4ab038722798da816533ce0a
Parents: 03679c9
Author: Christopher Collins <cc...@apache.org>
Authored: Fri Apr 8 18:14:11 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Fri Apr 8 18:19:32 2016 -0700
----------------------------------------------------------------------
net/nimble/host/src/ble_hs_misc.c | 7 +++
net/nimble/host/src/ble_l2cap.c | 3 ++
net/nimble/host/src/ble_l2cap_sm.c | 32 +++++++-----
net/nimble/host/src/ble_l2cap_sm_alg.c | 62 +++++++++++++----------
net/nimble/host/src/ble_l2cap_sm_cmd.c | 6 +++
net/nimble/host/src/host_hci_cmd.c | 16 +++++-
net/nimble/host/src/test/ble_l2cap_sm_test.c | 34 +++++--------
7 files changed, 98 insertions(+), 62 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c8d9ce1c/net/nimble/host/src/ble_hs_misc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_misc.c b/net/nimble/host/src/ble_hs_misc.c
index a02e456..8335196 100644
--- a/net/nimble/host/src/ble_hs_misc.c
+++ b/net/nimble/host/src/ble_hs_misc.c
@@ -88,6 +88,7 @@ struct os_mbuf *
ble_hs_misc_pkthdr(void)
{
struct os_mbuf *om;
+ int rc;
om = os_msys_get_pkthdr(0, 0);
if (om == NULL) {
@@ -95,6 +96,12 @@ ble_hs_misc_pkthdr(void)
}
/* Make room in the buffer for various headers. XXX Check this number. */
+ if (om->om_omp->omp_databuf_len < 8) {
+ rc = os_mbuf_free_chain(om);
+ BLE_HS_DBG_ASSERT_EVAL(rc == 0);
+ return NULL;
+ }
+
om->om_data += 8;
return om;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c8d9ce1c/net/nimble/host/src/ble_l2cap.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap.c b/net/nimble/host/src/ble_l2cap.c
index c7a29af..40bf225 100644
--- a/net/nimble/host/src/ble_l2cap.c
+++ b/net/nimble/host/src/ble_l2cap.c
@@ -308,6 +308,9 @@ ble_l2cap_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
goto err;
}
+ BLE_HS_LOG(DEBUG, "ble_l2cap_tx(): ");
+ ble_hs_misc_log_mbuf(om);
+ BLE_HS_LOG(DEBUG, "\n");
rc = host_hci_data_tx(conn, om);
om = NULL;
if (rc != 0) {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c8d9ce1c/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 15d654e..8ff79e0 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -713,6 +713,7 @@ static int
ble_l2cap_sm_random_kick(struct ble_l2cap_sm_proc *proc)
{
struct ble_l2cap_sm_pair_random cmd;
+ uint8_t key[16];
int rc;
memcpy(cmd.value, proc->phase_1_2.rand_our, 16);
@@ -723,6 +724,15 @@ ble_l2cap_sm_random_kick(struct ble_l2cap_sm_proc *proc)
}
if (!(proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR)) {
+ /* Generate the key. */
+ 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_l2cap_sm_gap_event(proc, rc, 0);
+ return rc;
+ }
+ memcpy(proc->hci.key, key, sizeof key);
+
proc->hci.handle = BLE_HCI_SCHED_HANDLE_NONE;
proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_LTK;
}
@@ -737,6 +747,7 @@ ble_l2cap_sm_random_handle(struct ble_l2cap_sm_proc *proc,
uint8_t preq[BLE_L2CAP_SM_HDR_SZ + BLE_L2CAP_SM_PAIR_CMD_SZ];
uint8_t pres[BLE_L2CAP_SM_HDR_SZ + BLE_L2CAP_SM_PAIR_CMD_SZ];
uint8_t confirm_val[16];
+ uint8_t key[16];
uint8_t k[16];
uint8_t ia[6];
uint8_t ra[6];
@@ -768,6 +779,14 @@ ble_l2cap_sm_random_handle(struct ble_l2cap_sm_proc *proc,
memcpy(proc->phase_1_2.rand_their, cmd->value, 16);
if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
+ /* Generate the key. */
+ 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_l2cap_sm_gap_event(proc, rc, 0);
+ return rc;
+ }
+ memcpy(proc->hci.key, key, sizeof key);
proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_START_ENCRYPT;
}
ble_l2cap_sm_proc_set_pending(proc);
@@ -853,20 +872,7 @@ static int
ble_l2cap_sm_lt_key_req_handle(struct ble_l2cap_sm_proc *proc,
struct hci_le_lt_key_req *evt)
{
- uint8_t key[16];
- int rc;
-
- /* Generate the key. */
- 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_l2cap_sm_gap_event(proc, rc, 0);
- return rc;
- }
-
ble_l2cap_sm_proc_set_pending(proc);
- memcpy(proc->hci.key, key, sizeof key);
-
return 0;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c8d9ce1c/net/nimble/host/src/ble_l2cap_sm_alg.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm_alg.c b/net/nimble/host/src/ble_l2cap_sm_alg.c
index 59ee6c5..61a9825 100644
--- a/net/nimble/host/src/ble_l2cap_sm_alg.c
+++ b/net/nimble/host/src/ble_l2cap_sm_alg.c
@@ -46,17 +46,11 @@ ble_l2cap_sm_alg_encrypt(uint8_t *key, uint8_t *plaintext, uint8_t *enc_data)
uint8_t tmp[16];
int rc;
- BLE_HS_LOG(DEBUG, "ble_l2cap_sm_alg_encrypt; key=");
- ble_hs_misc_log_flat_buf(key, 16);
- BLE_HS_LOG(DEBUG, " plaintext=");
- ble_hs_misc_log_flat_buf(plaintext, 16);
-
swap_buf(tmp, key, 16);
rc = mbedtls_aes_setkey_enc(&ble_l2cap_sm_alg_ctxt, tmp, 128);
if (rc != 0) {
- rc = BLE_HS_EUNKNOWN;
- goto done;
+ return BLE_HS_EUNKNOWN;
}
swap_buf(tmp, plaintext, 16);
@@ -64,25 +58,19 @@ ble_l2cap_sm_alg_encrypt(uint8_t *key, uint8_t *plaintext, uint8_t *enc_data)
rc = mbedtls_aes_crypt_ecb(&ble_l2cap_sm_alg_ctxt, MBEDTLS_AES_ENCRYPT,
tmp, enc_data);
if (rc != 0) {
- rc = BLE_HS_EUNKNOWN;
- goto done;
+ return BLE_HS_EUNKNOWN;
}
swap_in_place(enc_data, 16);
- BLE_HS_LOG(DEBUG, " enc_data=");
- ble_hs_misc_log_flat_buf(enc_data, 16);
-
- rc = 0;
-
-done:
- BLE_HS_LOG(DEBUG, "\n");
- return rc;
+ return 0;
}
int
ble_l2cap_sm_alg_s1(uint8_t *k, uint8_t *r1, uint8_t *r2, uint8_t *out)
{
+ int rc;
+
/* The most significant 64-bits of r1 are discarded to generate
* r1' and the most significant 64-bits of r2 are discarded to
* generate r2'.
@@ -95,7 +83,22 @@ ble_l2cap_sm_alg_s1(uint8_t *k, uint8_t *r1, uint8_t *r2, uint8_t *out)
memcpy(out + 8, r1, 8);
/* s1(k, r1 , r2) = e(k, r') */
- return ble_l2cap_sm_alg_encrypt(k, out, out);
+ rc = ble_l2cap_sm_alg_encrypt(k, out, out);
+ if (rc != 0) {
+ return rc;
+ }
+
+ BLE_HS_LOG(DEBUG, "ble_l2cap_sm_alg_s1()\n k=");
+ ble_hs_misc_log_flat_buf(k, 16);
+ BLE_HS_LOG(DEBUG, "\n r1=");
+ ble_hs_misc_log_flat_buf(r1, 16);
+ BLE_HS_LOG(DEBUG, "\n r2=");
+ ble_hs_misc_log_flat_buf(r2, 16);
+ BLE_HS_LOG(DEBUG, "\n out=");
+ ble_hs_misc_log_flat_buf(out, 16);
+ BLE_HS_LOG(DEBUG, "\n");
+
+ return 0;
}
int
@@ -108,18 +111,18 @@ ble_l2cap_sm_alg_c1(uint8_t *k, uint8_t *r,
uint8_t p1[16], p2[16];
int rc;
- BLE_HS_LOG(DEBUG, "ble_l2cap_sm_alg_c1; k=");
+ BLE_HS_LOG(DEBUG, "ble_l2cap_sm_alg_c1()\n k=");
ble_hs_misc_log_flat_buf(k, 16);
- BLE_HS_LOG(DEBUG, " r=");
+ BLE_HS_LOG(DEBUG, "\n r=");
ble_hs_misc_log_flat_buf(r, 16);
- BLE_HS_LOG(DEBUG, " iat=%d rat=%d", iat, rat);
- BLE_HS_LOG(DEBUG, " ia=");
+ BLE_HS_LOG(DEBUG, "\n iat=%d rat=%d", iat, rat);
+ BLE_HS_LOG(DEBUG, "\n ia=");
ble_hs_misc_log_flat_buf(ia, 6);
- BLE_HS_LOG(DEBUG, " ra=");
+ BLE_HS_LOG(DEBUG, "\n ra=");
ble_hs_misc_log_flat_buf(ra, 6);
- BLE_HS_LOG(DEBUG, " preq=");
+ BLE_HS_LOG(DEBUG, "\n preq=");
ble_hs_misc_log_flat_buf(preq, 7);
- BLE_HS_LOG(DEBUG, " pres=");
+ BLE_HS_LOG(DEBUG, "\n pres=");
ble_hs_misc_log_flat_buf(pres, 7);
/* pres, preq, rat and iat are concatenated to generate p1 */
@@ -128,7 +131,7 @@ ble_l2cap_sm_alg_c1(uint8_t *k, uint8_t *r,
memcpy(p1 + 2, preq, 7);
memcpy(p1 + 9, pres, 7);
- BLE_HS_LOG(DEBUG, " p1=");
+ BLE_HS_LOG(DEBUG, "\n p1=");
ble_hs_misc_log_flat_buf(p1, sizeof p1);
/* c1 = e(k, e(k, r XOR p1) XOR p2) */
@@ -147,7 +150,7 @@ ble_l2cap_sm_alg_c1(uint8_t *k, uint8_t *r,
memcpy(p2 + 6, ia, 6);
memset(p2 + 12, 0, 4);
- BLE_HS_LOG(DEBUG, " p2=");
+ BLE_HS_LOG(DEBUG, "\n p2=");
ble_hs_misc_log_flat_buf(p2, sizeof p2);
ble_l2cap_sm_alg_xor_128(out_enc_data, p2, out_enc_data);
@@ -158,10 +161,13 @@ ble_l2cap_sm_alg_c1(uint8_t *k, uint8_t *r,
goto done;
}
+ BLE_HS_LOG(DEBUG, "\n out_enc_data=");
+ ble_hs_misc_log_flat_buf(out_enc_data, 16);
+
rc = 0;
done:
- BLE_HS_LOG(DEBUG, "\n");
+ BLE_HS_LOG(DEBUG, "\n rc=%d\n", rc);
return rc;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c8d9ce1c/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 a83ce72..dac8558 100644
--- a/net/nimble/host/src/ble_l2cap_sm_cmd.c
+++ b/net/nimble/host/src/ble_l2cap_sm_cmd.c
@@ -40,6 +40,9 @@ ble_l2cap_sm_tx(uint16_t conn_handle, struct os_mbuf *txom)
rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SM,
&conn, &chan);
if (rc == 0) {
+ BLE_HS_LOG(DEBUG, "ble_l2cap_sm_tx(): ");
+ ble_hs_misc_log_mbuf(txom);
+ BLE_HS_LOG(DEBUG, "\n");
rc = ble_l2cap_tx(conn, chan, txom);
}
@@ -170,6 +173,9 @@ ble_l2cap_sm_pair_confirm_tx(uint16_t conn_handle,
ble_l2cap_sm_pair_confirm_write(txom->om_data, txom->om_len, cmd);
+ BLE_HS_LOG(DEBUG, "ble_l2cap_sm_pair_confirm_tx(): ");
+ ble_hs_misc_log_mbuf(txom);
+ BLE_HS_LOG(DEBUG, "\n");
rc = ble_l2cap_sm_tx(conn_handle, txom);
txom = NULL;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c8d9ce1c/net/nimble/host/src/host_hci_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_hci_cmd.c b/net/nimble/host/src/host_hci_cmd.c
index a4a4b81..bb4f8d4 100644
--- a/net/nimble/host/src/host_hci_cmd.c
+++ b/net/nimble/host/src/host_hci_cmd.c
@@ -741,6 +741,20 @@ host_hci_cmd_le_conn_update(struct hci_conn_update *hcu)
return rc;
}
+/**
+ * Sends the long-term key (LTK) to the controller.
+ *
+ * Note: This function expects the 128-bit key to be in little-endian byte
+ * order.
+ *
+ * OGF = 0x08 (LE)
+ * OCF = 0x001a
+ *
+ * @param key
+ * @param pt
+ *
+ * @return int
+ */
int
host_hci_cmd_le_lt_key_req_reply(struct hci_lt_key_req_reply *hkr)
{
@@ -878,7 +892,7 @@ host_hci_cmd_le_start_encrypt(struct hci_start_encrypt *cmd)
htole16(buf + 0, cmd->connection_handle);
htole64(buf + 2, cmd->random_number);
htole16(buf + 10, cmd->encrypted_diversifier);
- swap_buf(buf + 12, cmd->long_term_key, 16);
+ memcpy(buf + 12, cmd->long_term_key, sizeof cmd->long_term_key);
return host_hci_le_cmd_send(BLE_HCI_OCF_LE_START_ENCRYPT, sizeof buf, buf);
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c8d9ce1c/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 f29675c..722f12f 100644
--- a/net/nimble/host/src/test/ble_l2cap_sm_test.c
+++ b/net/nimble/host/src/test/ble_l2cap_sm_test.c
@@ -660,12 +660,6 @@ ble_l2cap_sm_test_util_us_lgcy_good(
ble_l2cap_sm_dbg_set_next_ediv(ediv);
ble_l2cap_sm_dbg_set_next_start_rand(r);
- ble_hs_cfg.sm_bonding = 1;
- ble_hs_cfg.sm_mitm = 1;
- ble_hs_cfg.sm_io_cap = 4;
- ble_hs_cfg.sm_our_key_dist = 0x07;
- ble_hs_cfg.sm_their_key_dist = 0x07;
-
conn = ble_hs_test_util_create_conn(2, rsp_addr,
ble_l2cap_sm_test_util_conn_cb,
NULL);
@@ -746,15 +740,15 @@ ble_l2cap_sm_test_util_us_lgcy_good(
TEST_CASE(ble_l2cap_sm_test_case_us_lgcy_jw_good)
{
ble_l2cap_sm_test_util_us_lgcy_good(
- ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
- ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+ ((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 = 0x04,
+ .io_cap = 3,
.oob_data_flag = 0,
- .authreq = 0x05,
+ .authreq = 0,
.max_enc_key_size = 16,
- .init_key_dist = 0x07,
- .resp_key_dist = 0x07,
+ .init_key_dist = 0,
+ .resp_key_dist = 0,
} }),
((struct ble_l2cap_sm_pair_cmd[1]) { {
.io_cap = 3,
@@ -766,20 +760,20 @@ TEST_CASE(ble_l2cap_sm_test_case_us_lgcy_jw_good)
} }),
((struct ble_l2cap_sm_pair_confirm[1]) { {
.value = {
- 0x0a, 0xac, 0xa2, 0xae, 0xa6, 0x98, 0xdc, 0x6d,
- 0x65, 0x84, 0x11, 0x69, 0x47, 0x36, 0x8d, 0xa0,
+ 0x04, 0x4e, 0xaf, 0xce, 0x30, 0x79, 0x2c, 0x9e,
+ 0xa2, 0xeb, 0x53, 0x6a, 0xdf, 0xf7, 0x99, 0xb2,
},
} }),
((struct ble_l2cap_sm_pair_confirm[1]) { {
.value = {
- 0x45, 0xd2, 0x2c, 0x38, 0xd8, 0x91, 0x4f, 0x19,
- 0xa2, 0xd4, 0xfc, 0x7d, 0xad, 0x37, 0x79, 0xe0
+ 0x04, 0x4e, 0xaf, 0xce, 0x30, 0x79, 0x2c, 0x9e,
+ 0xa2, 0xeb, 0x53, 0x6a, 0xdf, 0xf7, 0x99, 0xb2,
},
} }),
((struct ble_l2cap_sm_pair_random[1]) { {
.value = {
- 0x2b, 0x3b, 0x69, 0xe4, 0xef, 0xab, 0xcc, 0x48,
- 0x78, 0x20, 0x1a, 0x54, 0x7a, 0x91, 0x5d, 0xfb,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
} }),
((struct ble_l2cap_sm_pair_random[1]) { {
@@ -791,8 +785,8 @@ TEST_CASE(ble_l2cap_sm_test_case_us_lgcy_jw_good)
BLE_L2CAP_SM_PAIR_ALG_JW,
NULL,
((uint8_t[16]) {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
- 0x00, 0x03, 0x07, 0x07, 0x10, 0x05, 0x00, 0x04,
+ 0x2e, 0x2b, 0x34, 0xca, 0x59, 0xfa, 0x4c, 0x88,
+ 0x3b, 0x2c, 0x8a, 0xef, 0xd4, 0x4b, 0xe9, 0x66,
}),
0,
0