From 7b56d698d50a6dfd77f8820cc36919487fa27f52 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sun, 11 Dec 2016 23:44:02 +0100 Subject: [PATCH 1/7] nimble/test: Fix expected value in ble_sm_test_util_us_fail_inval Value from test def should be used, not hardcoded one. X-Original-Commit: a3f6ea1de07e04e302dd442a6b72ecfdeb1aed49 --- nimble/host/test/src/ble_sm_test_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/test/src/ble_sm_test_util.c b/nimble/host/test/src/ble_sm_test_util.c index 7f40ff930..faa38ff61 100644 --- a/nimble/host/test/src/ble_sm_test_util.c +++ b/nimble/host/test/src/ble_sm_test_util.c @@ -2408,7 +2408,7 @@ ble_sm_test_util_us_fail_inval(struct ble_sm_test_params *params) /* Receive a pair response from the peer. */ ble_sm_test_util_rx_pair_rsp( - 2, ¶ms->pair_rsp, BLE_HS_SM_US_ERR(BLE_SM_ERR_INVAL)); + 2, ¶ms->pair_rsp, BLE_HS_SM_US_ERR(params->pair_fail.reason)); TEST_ASSERT(!conn->bhc_sec_state.encrypted); TEST_ASSERT(ble_sm_dbg_num_procs() == 0); From 13fc8a872ebd5335b8fcebeb490d9587211d084a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sun, 11 Dec 2016 23:46:14 +0100 Subject: [PATCH 2/7] nimble/test: Fix expected error for key size lower than minimum For key size lower than minimum, an "Encryption Key Size" error shall be returned, not "Invalid Parameters". X-Original-Commit: c3f9aa1968a483183de60ad9a8bf43545fa0c36a --- nimble/host/test/src/ble_sm_test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/host/test/src/ble_sm_test.c b/nimble/host/test/src/ble_sm_test.c index a98f4bb11..5fd6c3d77 100644 --- a/nimble/host/test/src/ble_sm_test.c +++ b/nimble/host/test/src/ble_sm_test.c @@ -202,7 +202,7 @@ TEST_CASE(ble_sm_test_case_peer_fail_inval) .resp_key_dist = 0x07, } }), ((struct ble_sm_pair_fail[1]) { { - .reason = BLE_SM_ERR_INVAL, + .reason = BLE_SM_ERR_ENC_KEY_SZ, } }) ); @@ -457,7 +457,7 @@ TEST_CASE(ble_sm_test_case_us_fail_inval) .resp_key_dist = 0x07, }, .pair_fail = (struct ble_sm_pair_fail) { - .reason = BLE_SM_ERR_INVAL, + .reason = BLE_SM_ERR_ENC_KEY_SZ, }, }; ble_sm_test_util_us_fail_inval(¶ms); From 724e41d3fce590ac776ecb737c1c6b29c642c331 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sun, 11 Dec 2016 23:47:48 +0100 Subject: [PATCH 3/7] nimble/test: Remove invalid SM test cases Test cases which check for pairing failing on reserved values are invalid since reserved values shall be ignored as required by spec and pairing shall succeed. These test cases will be replaced with ones that check for pairing success when reserved bits are used. X-Original-Commit: 2e6367caef814958f65a644c8d41df765ef98ece --- nimble/host/test/src/ble_sm_test.c | 268 +---------------------------- 1 file changed, 2 insertions(+), 266 deletions(-) diff --git a/nimble/host/test/src/ble_sm_test.c b/nimble/host/test/src/ble_sm_test.c index 5fd6c3d77..0580821b3 100644 --- a/nimble/host/test/src/ble_sm_test.c +++ b/nimble/host/test/src/ble_sm_test.c @@ -188,78 +188,6 @@ TEST_CASE(ble_sm_test_case_peer_fail_inval) } }) ); - /* Invalid IO capabiltiies. */ - ble_sm_test_util_peer_fail_inval( - 0, - ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}), - ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}), - ((struct ble_sm_pair_cmd[1]) { { - .io_cap = 0x14, - .oob_data_flag = 0, - .authreq = 0x05, - .max_enc_key_size = 16, - .init_key_dist = 0x07, - .resp_key_dist = 0x07, - } }), - ((struct ble_sm_pair_fail[1]) { { - .reason = BLE_SM_ERR_ENC_KEY_SZ, - } }) - ); - - /* Invalid OOB flag. */ - ble_sm_test_util_peer_fail_inval( - 0, - ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}), - ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}), - ((struct ble_sm_pair_cmd[1]) { { - .io_cap = 0x04, - .oob_data_flag = 2, - .authreq = 0x05, - .max_enc_key_size = 16, - .init_key_dist = 0x07, - .resp_key_dist = 0x07, - } }), - ((struct ble_sm_pair_fail[1]) { { - .reason = BLE_SM_ERR_INVAL, - } }) - ); - - /* Invalid authreq - reserved bonding flag. */ - ble_sm_test_util_peer_fail_inval( - 0, - ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}), - ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}), - ((struct ble_sm_pair_cmd[1]) { { - .io_cap = 0x04, - .oob_data_flag = 0, - .authreq = 0x2, - .max_enc_key_size = 16, - .init_key_dist = 0x07, - .resp_key_dist = 0x07, - } }), - ((struct ble_sm_pair_fail[1]) { { - .reason = BLE_SM_ERR_INVAL, - } }) - ); - - /* Invalid authreq - reserved other flag. */ - ble_sm_test_util_peer_fail_inval( - 0, - ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}), - ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}), - ((struct ble_sm_pair_cmd[1]) { { - .io_cap = 0x04, - .oob_data_flag = 0, - .authreq = 0x20, - .max_enc_key_size = 16, - .init_key_dist = 0x07, - .resp_key_dist = 0x07, - } }), - ((struct ble_sm_pair_fail[1]) { { - .reason = BLE_SM_ERR_INVAL, - } }) - ); - /* Invalid key size - too small. */ ble_sm_test_util_peer_fail_inval( 0, @@ -274,7 +202,7 @@ TEST_CASE(ble_sm_test_case_peer_fail_inval) .resp_key_dist = 0x07, } }), ((struct ble_sm_pair_fail[1]) { { - .reason = BLE_SM_ERR_INVAL, + .reason = BLE_SM_ERR_ENC_KEY_SZ, } }) ); @@ -295,42 +223,6 @@ TEST_CASE(ble_sm_test_case_peer_fail_inval) .reason = BLE_SM_ERR_INVAL, } }) ); - - /* Invalid init key dist. */ - ble_sm_test_util_peer_fail_inval( - 0, - ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}), - ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}), - ((struct ble_sm_pair_cmd[1]) { { - .io_cap = 0x04, - .oob_data_flag = 0, - .authreq = 0x5, - .max_enc_key_size = 16, - .init_key_dist = 0x10, - .resp_key_dist = 0x07, - } }), - ((struct ble_sm_pair_fail[1]) { { - .reason = BLE_SM_ERR_INVAL, - } }) - ); - - /* Invalid resp key dist. */ - ble_sm_test_util_peer_fail_inval( - 0, - ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}), - ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}), - ((struct ble_sm_pair_cmd[1]) { { - .io_cap = 0x04, - .oob_data_flag = 0, - .authreq = 0x5, - .max_enc_key_size = 16, - .init_key_dist = 0x07, - .resp_key_dist = 0x10, - } }), - ((struct ble_sm_pair_fail[1]) { { - .reason = BLE_SM_ERR_INVAL, - } }) - ); } TEST_CASE(ble_sm_test_case_peer_lgcy_fail_confirm) @@ -436,110 +328,6 @@ TEST_CASE(ble_sm_test_case_us_fail_inval) { struct ble_sm_test_params params; - /* Invalid IO capabiltiies. */ - params = (struct ble_sm_test_params) { - .init_id_addr = {0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}, - .resp_id_addr = {0x03, 0x02, 0x01, 0x50, 0x13, 0x00}, - .pair_req = (struct ble_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_sm_pair_cmd) { - .io_cap = 0x14, - .oob_data_flag = 0, - .authreq = 0x05, - .max_enc_key_size = 16, - .init_key_dist = 0x07, - .resp_key_dist = 0x07, - }, - .pair_fail = (struct ble_sm_pair_fail) { - .reason = BLE_SM_ERR_ENC_KEY_SZ, - }, - }; - ble_sm_test_util_us_fail_inval(¶ms); - - /* Invalid OOB flag. */ - params = (struct ble_sm_test_params) { - .init_id_addr = {0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}, - .resp_id_addr = {0x03, 0x02, 0x01, 0x50, 0x13, 0x00}, - .pair_req = (struct ble_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_sm_pair_cmd) { - .io_cap = 0x14, - .oob_data_flag = 2, - .authreq = 0x05, - .max_enc_key_size = 16, - .init_key_dist = 0x07, - .resp_key_dist = 0x07, - }, - .pair_fail = (struct ble_sm_pair_fail) { - .reason = BLE_SM_ERR_INVAL, - }, - }; - ble_sm_test_util_us_fail_inval(¶ms); - - /* Invalid authreq - reserved bonding flag. */ - params = (struct ble_sm_test_params) { - .init_id_addr = {0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}, - .resp_id_addr = {0x03, 0x02, 0x01, 0x50, 0x13, 0x00}, - .pair_req = (struct ble_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_sm_pair_cmd) { - .io_cap = 0x04, - .oob_data_flag = 0, - .authreq = 0x02, - .max_enc_key_size = 16, - .init_key_dist = 0x07, - .resp_key_dist = 0x07, - }, - .pair_fail = (struct ble_sm_pair_fail) { - .reason = BLE_SM_ERR_INVAL, - }, - }; - ble_sm_test_util_us_fail_inval(¶ms); - - /* Invalid authreq - reserved other flag. */ - params = (struct ble_sm_test_params) { - .init_id_addr = {0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}, - .resp_id_addr = {0x03, 0x02, 0x01, 0x50, 0x13, 0x00}, - .pair_req = (struct ble_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_sm_pair_cmd) { - .io_cap = 0x04, - .oob_data_flag = 0, - .authreq = 0x20, - .max_enc_key_size = 16, - .init_key_dist = 0x07, - .resp_key_dist = 0x07, - }, - .pair_fail = (struct ble_sm_pair_fail) { - .reason = BLE_SM_ERR_INVAL, - }, - }; - ble_sm_test_util_us_fail_inval(¶ms); - /* Invalid key size - too small. */ params = (struct ble_sm_test_params) { .init_id_addr = {0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}, @@ -561,7 +349,7 @@ TEST_CASE(ble_sm_test_case_us_fail_inval) .resp_key_dist = 0x07, }, .pair_fail = (struct ble_sm_pair_fail) { - .reason = BLE_SM_ERR_INVAL, + .reason = BLE_SM_ERR_ENC_KEY_SZ, }, }; ble_sm_test_util_us_fail_inval(¶ms); @@ -591,58 +379,6 @@ TEST_CASE(ble_sm_test_case_us_fail_inval) }, }; ble_sm_test_util_us_fail_inval(¶ms); - - /* Invalid init key dist. */ - params = (struct ble_sm_test_params) { - .init_id_addr = {0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}, - .resp_id_addr = {0x03, 0x02, 0x01, 0x50, 0x13, 0x00}, - .pair_req = (struct ble_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_sm_pair_cmd) { - .io_cap = 0x04, - .oob_data_flag = 0, - .authreq = 0x05, - .max_enc_key_size = 17, - .init_key_dist = 0x10, - .resp_key_dist = 0x07, - }, - .pair_fail = (struct ble_sm_pair_fail) { - .reason = BLE_SM_ERR_INVAL, - }, - }; - ble_sm_test_util_us_fail_inval(¶ms); - - /* Invalid resp key dist. */ - params = (struct ble_sm_test_params) { - .init_id_addr = {0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}, - .resp_id_addr = {0x03, 0x02, 0x01, 0x50, 0x13, 0x00}, - .pair_req = (struct ble_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_sm_pair_cmd) { - .io_cap = 0x04, - .oob_data_flag = 0, - .authreq = 0x05, - .max_enc_key_size = 16, - .init_key_dist = 0x07, - .resp_key_dist = 0x10, - }, - .pair_fail = (struct ble_sm_pair_fail) { - .reason = BLE_SM_ERR_INVAL, - }, - }; - ble_sm_test_util_us_fail_inval(¶ms); } TEST_SUITE(ble_sm_gen_test_suite) From 29c4294df647d2000ddca5694352af9238796ccd Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 15 Nov 2016 22:56:02 +0100 Subject: [PATCH 4/7] nimble/sm: Fix AuthReq/KeyDist validation in pairing req/rsp The reserved bits in AuthReq and key distribution flags shall be ignored on reception thus non-zero values do not make pairing command invalid. This is to ensure compatibility with future specs. This fixes following PTS test cases for SM: - TP/JW/BI-03-C - TP/JW/BI-04-C Reference: Bluetooth Specification 4.2, Vol 3, Part H, Section 3.5.2 Bluetooth Specification 4.2, Vol 3, Part H, Section 3.6.1 X-Original-Commit: 9627249a1fd3ce031fdca821646692adb9ebe31a --- nimble/host/src/ble_sm_cmd.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/nimble/host/src/ble_sm_cmd.c b/nimble/host/src/ble_sm_cmd.c index 34609c6c8..e438c023b 100644 --- a/nimble/host/src/ble_sm_cmd.c +++ b/nimble/host/src/ble_sm_cmd.c @@ -101,24 +101,12 @@ ble_sm_pair_cmd_is_valid(struct ble_sm_pair_cmd *cmd) return 0; } - if (cmd->authreq & BLE_SM_PAIR_AUTHREQ_RESERVED) { - return 0; - } - if (cmd->max_enc_key_size < BLE_SM_PAIR_KEY_SZ_MIN || cmd->max_enc_key_size > BLE_SM_PAIR_KEY_SZ_MAX) { return 0; } - if (cmd->init_key_dist & BLE_SM_PAIR_KEY_DIST_RESERVED) { - return 0; - } - - if (cmd->resp_key_dist & BLE_SM_PAIR_KEY_DIST_RESERVED) { - return 0; - } - return 1; } From ffa0636719391c464c565dbf93e2cb3427f653b1 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 22 Nov 2016 21:09:22 +0100 Subject: [PATCH 5/7] nimble/sm: Improve pairing req/rsp validation The "Invalid Parameters" error code is only valid if encryption key size it larger than allowed maximum - if it is lower than supported minimum key size, the error code shall be "Encryption Key Size". Also we should accept pairing req/rsp in case either IO Capabilities or OOB Flags are set to reserved values by forcing either Just Works or discarding OOB Flags information respectively. This should allow to handle pairing with future specs (if reserved values are used) and is inline with other stacks (e.g. BlueZ, Zephyr). X-Original-Commit: 3d129607c9078bde96753208d35829e2c762e8ae --- nimble/host/src/ble_sm.c | 12 +++++++++--- nimble/host/src/ble_sm_cmd.c | 21 --------------------- nimble/host/src/ble_sm_lgcy.c | 6 +++++- nimble/host/src/ble_sm_sc.c | 6 +++++- 4 files changed, 19 insertions(+), 26 deletions(-) diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 67e8728de..d6527d4f0 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -1487,9 +1487,12 @@ ble_sm_pair_req_rx(uint16_t conn_handle, uint8_t op, struct os_mbuf **om, if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) { res->sm_err = BLE_SM_ERR_CMD_NOT_SUPP; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CMD_NOT_SUPP); - } else if (!ble_sm_pair_cmd_is_valid(&req)) { + } else if (req.max_enc_key_size < BLE_SM_PAIR_KEY_SZ_MIN) { + res->sm_err = BLE_SM_ERR_ENC_KEY_SZ; + res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_ENC_KEY_SZ); + } else if (req.max_enc_key_size > BLE_SM_PAIR_KEY_SZ_MAX) { res->sm_err = BLE_SM_ERR_INVAL; - res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_INVAL); + res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_INVAL); } else { res->execute = 1; } @@ -1520,7 +1523,10 @@ ble_sm_pair_rsp_rx(uint16_t conn_handle, uint8_t op, struct os_mbuf **om, proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_PAIR, 1, &prev); if (proc != NULL) { proc->pair_rsp = rsp; - if (!ble_sm_pair_cmd_is_valid(&rsp)) { + if (rsp.max_enc_key_size < BLE_SM_PAIR_KEY_SZ_MIN) { + res->sm_err = BLE_SM_ERR_ENC_KEY_SZ; + res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_ENC_KEY_SZ); + } else if (rsp.max_enc_key_size > BLE_SM_PAIR_KEY_SZ_MAX) { res->sm_err = BLE_SM_ERR_INVAL; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_INVAL); } else { diff --git a/nimble/host/src/ble_sm_cmd.c b/nimble/host/src/ble_sm_cmd.c index e438c023b..67fa1b098 100644 --- a/nimble/host/src/ble_sm_cmd.c +++ b/nimble/host/src/ble_sm_cmd.c @@ -90,26 +90,6 @@ ble_sm_pair_cmd_parse(void *payload, int len, struct ble_sm_pair_cmd *cmd) cmd->resp_key_dist = u8ptr[5]; } -int -ble_sm_pair_cmd_is_valid(struct ble_sm_pair_cmd *cmd) -{ - if (cmd->io_cap >= BLE_SM_IO_CAP_RESERVED) { - return 0; - } - - if (cmd->oob_data_flag >= BLE_SM_PAIR_OOB_RESERVED) { - return 0; - } - - if (cmd->max_enc_key_size < BLE_SM_PAIR_KEY_SZ_MIN || - cmd->max_enc_key_size > BLE_SM_PAIR_KEY_SZ_MAX) { - - return 0; - } - - return 1; -} - void ble_sm_pair_cmd_write(void *payload, int len, int is_req, struct ble_sm_pair_cmd *cmd) @@ -143,7 +123,6 @@ ble_sm_pair_cmd_tx(uint16_t conn_handle, int is_req, ble_sm_pair_cmd_write(txom->om_data, txom->om_len, is_req, cmd); BLE_SM_LOG_CMD(1, is_req ? "pair req" : "pair rsp", conn_handle, ble_sm_pair_cmd_log, cmd); - BLE_HS_DBG_ASSERT(ble_sm_pair_cmd_is_valid(cmd)); rc = ble_sm_tx(conn_handle, txom); if (rc != 0) { diff --git a/nimble/host/src/ble_sm_lgcy.c b/nimble/host/src/ble_sm_lgcy.c index ddc666de9..a77671e32 100644 --- a/nimble/host/src/ble_sm_lgcy.c +++ b/nimble/host/src/ble_sm_lgcy.c @@ -65,12 +65,16 @@ ble_sm_lgcy_io_action(struct ble_sm_proc *proc) { int action; - if (proc->pair_req.oob_data_flag && proc->pair_rsp.oob_data_flag) { + if (proc->pair_req.oob_data_flag == BLE_SM_PAIR_OOB_YES && + proc->pair_rsp.oob_data_flag == BLE_SM_PAIR_OOB_YES) { action = BLE_SM_IOACT_OOB; } else if (!(proc->pair_req.authreq & BLE_SM_PAIR_AUTHREQ_MITM) && !(proc->pair_rsp.authreq & BLE_SM_PAIR_AUTHREQ_MITM)) { action = BLE_SM_IOACT_NONE; + } else if (proc->pair_req.io_cap >= BLE_SM_IO_CAP_RESERVED || + proc->pair_rsp.io_cap >= BLE_SM_IO_CAP_RESERVED) { + action = BLE_SM_IOACT_NONE; } else if (proc->flags & BLE_SM_PROC_F_INITIATOR) { action = ble_sm_lgcy_init_ioa[proc->pair_rsp.io_cap] [proc->pair_req.io_cap]; diff --git a/nimble/host/src/ble_sm_sc.c b/nimble/host/src/ble_sm_sc.c index 11b29a1c8..f8a698305 100644 --- a/nimble/host/src/ble_sm_sc.c +++ b/nimble/host/src/ble_sm_sc.c @@ -112,12 +112,16 @@ ble_sm_sc_io_action(struct ble_sm_proc *proc) { int action; - if (proc->pair_req.oob_data_flag || proc->pair_rsp.oob_data_flag) { + if (proc->pair_req.oob_data_flag == BLE_SM_PAIR_OOB_YES || + proc->pair_rsp.oob_data_flag == BLE_SM_PAIR_OOB_YES) { action = BLE_SM_IOACT_OOB; } else if (!(proc->pair_req.authreq & BLE_SM_PAIR_AUTHREQ_MITM) && !(proc->pair_rsp.authreq & BLE_SM_PAIR_AUTHREQ_MITM)) { action = BLE_SM_IOACT_NONE; + } else if (proc->pair_req.io_cap >= BLE_SM_IO_CAP_RESERVED || + proc->pair_rsp.io_cap >= BLE_SM_IO_CAP_RESERVED) { + action = BLE_SM_IOACT_NONE; } else if (proc->flags & BLE_SM_PROC_F_INITIATOR) { action = ble_sm_sc_init_ioa[proc->pair_rsp.io_cap] [proc->pair_req.io_cap]; From 2e98ab6ecc80255b50845de7256901369ee0bf61 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 22 Nov 2016 23:46:31 +0100 Subject: [PATCH 6/7] nimble/sm: Use proper key size for encryption This patch adds proper masking of STK/LTK keys depending on encryption key size as defined in Bluetooth Specification 4.2, Vol 3, Part H, Section 2.3.4. This also fixes following PTS test cases for SM: - TP/EKS/BV-01-C - TP/EKS/BV-02-C X-Original-Commit: a034ac10ac6b02413e47f8d74652c99eae3763c3 --- nimble/host/src/ble_sm.c | 10 ++++++++-- nimble/host/src/ble_sm_lgcy.c | 5 ++++- nimble/host/src/ble_sm_priv.h | 1 + nimble/host/src/ble_sm_sc.c | 3 +++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index d6527d4f0..f42a54e36 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -314,11 +314,14 @@ ble_sm_gen_ltk(struct ble_sm_proc *proc, uint8_t *ltk) } #endif - rc = ble_hs_hci_util_rand(ltk, 16); + rc = ble_hs_hci_util_rand(ltk, proc->key_size); if (rc != 0) { return rc; } + /* Ensure proper key size */ + memset(ltk + proc->key_size, 0, sizeof proc->ltk - proc->key_size); + return 0; } @@ -1377,6 +1380,9 @@ ble_sm_pair_cfg(struct ble_sm_proc *proc) if (rx_key_dist & BLE_SM_PAIR_KEY_DIST_SIGN) { proc->rx_key_flags |= BLE_SM_KE_F_SIGN_INFO; } + + proc->key_size = min(proc->pair_req.max_enc_key_size, + proc->pair_rsp.max_enc_key_size); } static void @@ -1393,7 +1399,7 @@ ble_sm_pair_exec(struct ble_sm_proc *proc, struct ble_sm_result *res, cmd.io_cap = ble_hs_cfg.sm_io_cap; cmd.oob_data_flag = ble_hs_cfg.sm_oob_data_flag; cmd.authreq = ble_sm_build_authreq(); - cmd.max_enc_key_size = 16; + cmd.max_enc_key_size = BLE_SM_PAIR_KEY_SZ_MAX; if (is_req) { cmd.init_key_dist = ble_hs_cfg.sm_our_key_dist; diff --git a/nimble/host/src/ble_sm_lgcy.c b/nimble/host/src/ble_sm_lgcy.c index a77671e32..54a2ecb15 100644 --- a/nimble/host/src/ble_sm_lgcy.c +++ b/nimble/host/src/ble_sm_lgcy.c @@ -181,7 +181,10 @@ ble_sm_gen_stk(struct ble_sm_proc *proc) return rc; } - memcpy(proc->ltk, key, sizeof key); + memcpy(proc->ltk, key, proc->key_size); + + /* Ensure proper key size */ + memset(proc->ltk + proc->key_size, 0, sizeof key - proc->key_size); return 0; } diff --git a/nimble/host/src/ble_sm_priv.h b/nimble/host/src/ble_sm_priv.h index 7d96164b0..d75d4756e 100644 --- a/nimble/host/src/ble_sm_priv.h +++ b/nimble/host/src/ble_sm_priv.h @@ -257,6 +257,7 @@ struct ble_sm_proc { uint8_t pair_alg; uint8_t state; uint8_t rx_key_flags; + uint8_t key_size; struct ble_sm_pair_cmd pair_req; struct ble_sm_pair_cmd pair_rsp; diff --git a/nimble/host/src/ble_sm_sc.c b/nimble/host/src/ble_sm_sc.c index f8a698305..647160766 100644 --- a/nimble/host/src/ble_sm_sc.c +++ b/nimble/host/src/ble_sm_sc.c @@ -440,6 +440,9 @@ ble_sm_sc_random_rx(struct ble_sm_proc *proc, struct ble_sm_result *res) return; } + /* Ensure proper key size */ + memset(proc->ltk + proc->key_size, 0, sizeof proc->ltk - proc->key_size); + /* Ensure the ltk gets persisted when the pairing procedure succeeds. */ memcpy(proc->our_keys.ltk, proc->ltk, sizeof proc->our_keys.ltk); proc->our_keys.ltk_valid = 1; From 4a9cfc7e627f7076b23b20ea3748383ded610eaa Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 29 Nov 2016 11:31:01 +0100 Subject: [PATCH 7/7] nimble/sm: Fix obvious array size mismatch X-Original-Commit: 838b53a5c4712269edf3b747992fb8befa38412a --- nimble/host/src/ble_sm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index f42a54e36..a49c3d20e 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -498,7 +498,7 @@ ble_sm_persist_keys(struct ble_sm_proc *proc) { struct ble_store_value_sec value_sec; struct ble_hs_conn *conn; - uint8_t peer_addr[8]; + uint8_t peer_addr[6]; uint8_t peer_addr_type; int authenticated;