Skip to content
Permalink
Browse files

Bluetooth: Mesh: Fix rejecting invalid remote public key

The code was already rejecting the key, however that rejection
happened only after we had already sent our public key as response,
which got interpreted as acceptance by the tester (PTS).

This fixes issue that d4fd267
supposed to fix. The problem is bt_dh_key_gen is async.
Local public key cannot be sent from the same context
the bt_dh_key_gen is called because we don't know yet
if remote key is valid.

Fixes MESH/NODE/PROV/BI-13-C.

Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
  • Loading branch information...
MariuszSkamra authored and carlescufi committed Jul 19, 2019
1 parent ade6cc6 commit 83b50f6bee763917da3ce4eae1be7417d98af8c7
Showing with 35 additions and 49 deletions.
  1. +35 −49 subsys/bluetooth/mesh/prov.c
@@ -108,7 +108,6 @@
enum {
REMOTE_PUB_KEY, /* Remote key has been received */
LINK_ACTIVE, /* Link has been opened */
HAVE_DHKEY, /* DHKey has been calculated */
SEND_CONFIRM, /* Waiting to send Confirm value */
WAIT_NUMBER, /* Waiting for number input from user */
WAIT_STRING, /* Waiting for string input from user */
@@ -838,10 +837,6 @@ int bt_mesh_input_number(u32_t num)

send_input_complete();

if (!atomic_test_bit(link.flags, HAVE_DHKEY)) {
return 0;
}

if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
send_confirm();
}
@@ -861,48 +856,30 @@ int bt_mesh_input_string(const char *str)

send_input_complete();

if (!atomic_test_bit(link.flags, HAVE_DHKEY)) {
return 0;
}

if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
send_confirm();
}

return 0;
}

static void prov_dh_key_cb(const u8_t key[32])
static void send_pub_key(const u8_t dhkey[32])
{
BT_DBG("%p", key);
PROV_BUF(buf, 65);
const u8_t *key;

if (!key) {
BT_DBG("%p", dhkey);

if (!dhkey) {
BT_ERR("DHKey generation failed");
prov_send_fail_msg(PROV_ERR_UNEXP_ERR);
return;
}

sys_memcpy_swap(link.dhkey, key, 32);
sys_memcpy_swap(link.dhkey, dhkey, 32);

BT_DBG("DHkey: %s", bt_hex(link.dhkey, 32));

atomic_set_bit(link.flags, HAVE_DHKEY);

if (atomic_test_bit(link.flags, WAIT_NUMBER) ||
atomic_test_bit(link.flags, WAIT_STRING)) {
return;
}

if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
send_confirm();
}
}

static void send_pub_key(void)
{
PROV_BUF(buf, 65);
const u8_t *key;

key = bt_pub_key_get();
if (!key) {
BT_ERR("No public key available");
@@ -912,20 +889,6 @@ static void send_pub_key(void)

BT_DBG("Local Public Key: %s", bt_hex(key, 64));

/* Copy remote key in little-endian for bt_dh_key_gen().
* X and Y halves are swapped independently. Use response
* buffer as a temporary storage location. The bt_dh_key_gen()
* will also take care of validating the remote public key.
*/
sys_memcpy_swap(buf.data, &link.conf_inputs[17], 32);
sys_memcpy_swap(&buf.data[32], &link.conf_inputs[49], 32);

if (bt_dh_key_gen(buf.data, prov_dh_key_cb)) {
BT_ERR("Failed to generate DHKey");
prov_send_fail_msg(PROV_ERR_UNEXP_ERR);
return;
}

prov_buf_init(&buf, PROV_PUB_KEY);

/* Swap X and Y halves independently to big-endian */
@@ -939,9 +902,28 @@ static void send_pub_key(void)
return;
}

atomic_set_bit(link.flags, SEND_CONFIRM);
link.expect = PROV_CONFIRM;
}

static void prov_dh_key_gen(void)
{
u8_t remote_pk[64];

/* Copy remote key in little-endian for bt_dh_key_gen().
* X and Y halves are swapped independently. Use response
* buffer as a temporary storage location. The bt_dh_key_gen()
* will also take care of validating the remote public key.
*/
sys_memcpy_swap(remote_pk, &link.conf_inputs[17], 32);
sys_memcpy_swap(&remote_pk[32], &link.conf_inputs[49], 32);

if (bt_dh_key_gen(remote_pk, send_pub_key)) {
BT_ERR("Failed to generate DHKey");
prov_send_fail_msg(PROV_ERR_UNEXP_ERR);
}
}

static void prov_pub_key(const u8_t *data)
{
BT_DBG("Remote Public Key: %s", bt_hex(data, 64));
@@ -958,7 +940,7 @@ static void prov_pub_key(const u8_t *data)
return;
}

send_pub_key();
prov_dh_key_gen();
}

static void pub_key_ready(const u8_t *pkey)
@@ -971,7 +953,7 @@ static void pub_key_ready(const u8_t *pkey)
BT_DBG("Local public key ready");

if (atomic_test_and_clear_bit(link.flags, REMOTE_PUB_KEY)) {
send_pub_key();
prov_dh_key_gen();
}
}

@@ -986,12 +968,16 @@ static void prov_confirm(const u8_t *data)

memcpy(link.conf, data, 16);

if (!atomic_test_bit(link.flags, HAVE_DHKEY)) {
if (atomic_test_bit(link.flags, WAIT_NUMBER) ||
atomic_test_bit(link.flags, WAIT_STRING)) {
/* Clear retransmit timer */
#if defined(CONFIG_BT_MESH_PB_ADV)
prov_clear_tx();
#endif
atomic_set_bit(link.flags, SEND_CONFIRM);
} else {
return;
}

if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
send_confirm();
}
}

0 comments on commit 83b50f6

Please sign in to comment.
You can’t perform that action at this time.